当前位置: 首页 > news >正文

3. 认识 const

1. const 位置

  • 除了修饰一个类的成员函数外,不会出现在一条语句的最后。
  • 引用本身可以理解为指针常量,在引用前使用 const 没有意义。
  • 理解:先看离变量名最近的是啥

1.1 int const *p;

  • 离 p 最近的是 *,所以 p 首先是一个指针;接着,剩下的就是 p 指向的类型,也即 int const(整型常变量),所以 const 修饰的是 int,p 是一个常量指针。等价于 const int *p;
  • 也就是 p 指向的内容是不能改变的。

在这里插入图片描述

1.2 int * const p;

  • 离 p 最近的是 const,所以 p 是一个变量,类型是 int * const,所以 const 修饰的是 int*,p 是一个指针常量
  • 也就是 p 本身是不能改变的。

在这里插入图片描述

1.3 int const * *p;

  • 离 p 最近的是 *,p 首先是一个指针,指向的是 int const *。对于int const *来说,首先是一个指针,指向的是int const,所以是一个整型常量指针。所以 p 是一个指向整型常量的指针的指针。
  • 也就是 p 指向的是一个地址,这个地址上还是另一个地址,这个另一个地址上的内容是不可修改的 int(整型常量)。

在这里插入图片描述
在这里插入图片描述

1.4 int * const * p;

  • 离 p 最近的是 *,p 首先是一个指针,指向的类型是 int * const(整型指针常量),const 修饰的是 int*。
  • 也就是,p 指向的是一个地址,这个地址里面是另一个地址,这个另一个地址是不能被改变的。

在这里插入图片描述
这里 ptr_a 指向 a 的地址,ptr_a = a 的地址,所以 *ptr_a = a的内容;p 指向 ptr_a 的地址,p = ptr_a 的地址,所以 *p = ptr_a 的内容,也就是 a 的地址。

在这里插入图片描述

2. const 对象和对象的 const 成员

  • 用 const 修饰的类的对象称为常对象,用 const 修饰的类成员函数称为常函数。
#include <iostream>
using namespace std;class A {int num;
public:A() { num = 5;} void disp();void disp() const;void set(int n) { num = n; }
};void A::disp() {cout << num << endl; 
}void A::disp() const {cout << num << endl;
}int main() {A a1;a1.set(3);a1.disp();A const a2;a2.disp();return 0;
}

在这里插入图片描述

  • 声明和定义部分:
    • const 函数的声明和定义分开时,都需要加上 const,否则编译报错。
    • 只有类的非静态成员函数可以被声明为 const,原因是静态成员函数不含 this 指针,属于类级别的函数。
    • 普通函数不能声明为 const。
    • 在非 const 对象中,部分数据成员可以 const 修饰。类对象的非静态常量成员只能借助初始化列表进行初始化。构造函数中通过赋值运算符进行的是赋值,不是初始化。
  • 构成重载关系
    • 一个类的两个成员函数,一个 const 函数,一个普通函数,将构成重载关系,返回值类型、函数名、函数的参数列表完全相同。
      • 如:一个被看成 void disp(A*),一个看成 void disp(const A*),从而构成重载。
    • 对于非 const 对象 a1,先寻找普通函数,再寻找 const 版本。对于常对象 a2,只能调用 const 版本。
  • 当存在 const 版本和普通版本的成员函数时,若普通对象想调用 const 成员函数,则需要通过建立该对象的常引用或者指向该对象的常指针来实现。比如:( (const A&)a1).disp();或者( (const A*)&a1)->disp();

3. const 修饰函数参数和函数的返回值

  • 函数参数和返回值的 const,主要为了让编译器检查只读。
  • 当 const 修饰数值类型的形参时,不构成函数重载,如 void disp(const int i) 和 void disp(int i)。
    • 但当 const 修饰的是引用或指针的形参时,就是重载,如 void disp(const int& i) 和 void disp(int& i)。

4. 常见的 const 错误理解

  • const 修饰的变量一定不能修改,错误。
    • 当 const 修饰的局部变量存储在非只读存储器中,通过指针可以间接修改。

在这里插入图片描述

  • const 引用和 const 指针只能指向常变量,错误。
    • const 引用和 const 指针,只能说明不能通过该引用或指针去修改被引用的对象,至于被引用对象原来是什么性质是无法通过 const 引用和 const 指针决定的。

在这里插入图片描述
在这里插入图片描述

5. const ⇒ 非 const

C++ 中的 const_cast 可以去除 const 或 volatile 属性。

在这里插入图片描述

  • const_cast 只能去除目标的 const 或 volatile 属性,不能进行不同类型的转换。如下,不能由 const int[ ],转换为 int&。

在这里插入图片描述

  • const_cast 取消的是间接引用时的改写权限,变量原来的 const 不能去除。

在这里插入图片描述

6. C++ 和 C 中的 const 区别

  • 通常 C++ 碰见 const 声明时在 符号表 中放入常量
    • 编译过程中若发现使用常量则 直接以符号表中的值替换
    • 编译过程中若发现下述情况则给对应的常量分配空间:
      • 对 const 常量 使用了 extern
      • 对 const 常量 使用了 & 操作符

在这里插入图片描述

http://www.dtcms.com/a/393649.html

相关文章:

  • 云原生 vs 传统部署
  • 2.1、机器学习-模型评估指标与参数调优
  • 设计模式(C++)详解—享元模式(2)
  • Linux实用操作以及基础命令
  • 深入理解 Vue 插槽:从基础到高级用法
  • 自动排班系统:劳动力管理新选择
  • Word和WPS文字中设置了倍数行距却没有变化?原因和调整方法
  • 【Linux篇】Linux 初探:历史溯源与常用指令速览
  • 数字孪生及其在能源和新材料等领域内的应用
  • DeepSeek后训练:监督微调策略,开启模型优化新时代
  • 基于规则的专家系统对自然语言处理深层语义分析的影响与启示研究
  • 设计模式学习[19]---单例模式(饿汉式/懒汉式)
  • 基于哈希表与差分前缀和解决撒狗粮问题
  • 基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
  • 残差分析:数据驱动下线性模型的“体检师”与优化指南
  • gorm速成
  • 模型和策略:风控体系的“左右手”之争
  • Keil5 5.38版本在使用STLINK时闪退
  • win11 安装 WSL2 Ubuntu 并支持远程 SSH 登录
  • 基分析积分法则
  • 【Linux】网络——HTTP协议,HTTPS加密
  • HarmonyOS动画:属性动画、显示动画、转场动画
  • Redis 持久化机制详解:RDB 与 AOF 原理与实践
  • 【嵌入式协议外设篇】-8×8 点阵屏
  • 【C++:STL】深入详解string类(一):从读文档开始
  • 电商项目实战总结
  • 22.元类、静态鸭子类型、抽象基类
  • 【论文速递】2025年第21周(May-18-24)(Robotics/Embodied AI/LLM)
  • Android 自定义电池组件(BatteryView)
  • 基于 Stripe/Metering 的用量计费:从 SLO 指标到账单流水