const成员函数承诺不修改对象状态,仅允许访问mutable成员;const成员变量须在初始化列表中赋值;const参数影响绑定规则;const_cast滥用易致未定义行为;const性在继承中不可取消。

const成员函数表示“不修改对象状态”
它告诉编译器和调用者:这个函数不会改变 this 指向的对象的任何非 mutable 成员。编译器会检查函数体内是否对非 mutable 成员赋值、调用非 const 成员函数,一旦违反就报错,比如:error: assignment of member 'x' in read-only object。
常见误操作包括在 const 成员函数里调用 set_value()、给 count++、或返回 data_ 的非常量引用。这些都会触发编译失败。
- 只有
const成员函数能被const对象调用(例如const MyClass obj; obj.get_x();) -
const成员函数可以访问mutable成员(如缓存、计数器),这是唯一允许修改的例外 - 重载时,
const和非const版本可共存,编译器按对象是否为const自动选择(如operator[]的两种实现)
const修饰类成员变量 = 编译期只读初始化
声明为 const 的成员变量(如 const int id_;)必须在构造函数的 member initializer list 中初始化,不能在构造函数体里赋值。否则编译报错:error: uninitialized const member。
它不是运行时保护,而是强制约束:没有默认值、不可被修改、不可被赋值,连移动/拷贝构造函数也不能绕过该限制。
立即学习“C++免费学习笔记(深入)”;
- 不能写
id_ = 42;在构造函数内部 —— 必须写成MyClass(int x) : id_(x) {} - 不能用
std::move或std::swap修改它,哪怕通过const_cast强转也属于未定义行为 - 若类型是自定义类,其默认构造函数不会被调用;必须显式初始化,且该类型需支持
const构造
const修饰成员函数参数影响重载与隐式转换
参数加 const(如 void foo(const std::string& s))本身不构成重载区分依据,但结合引用类型和顶层 const,会影响绑定规则和函数匹配优先级。
真正关键的是:当参数是 const T& 时,它能接受临时对象、字面量、const 变量;而 T& 只能绑定非常量左值。这点在设计接口时直接影响可用性。
- 写
void set_name(std::string&&)和void set_name(const std::string&)可实现移动+拷贝双路径 - 传入字符串字面量
"abc"时,只能匹配const char*或const std::string&,不能匹配std::string& - 避免把参数写成
const std::string(值传递+const)—— 多一次无谓拷贝,且const在值参上无实际意义
const_cast不是用来“去掉const”的工具
在 const 成员函数中用 const_cast 强转 this 指针去修改成员,仅在目标原本就非 const 时合法(例如外部对象是 MyClass obj;,内部调用 const_cast)。如果对象本身是 const(如 const MyClass obj;),这么做就是未定义行为。
实际工程中,99% 的 const_cast 都是设计缺陷的信号:要么该成员应声明为 mutable,要么不该在 const 函数里改它,要么接口不该标记为 const。
-
mutable是唯一被标准认可的、在const成员函数中修改数据的合法方式 - 用
const_cast绕过const约束,往往意味着封装边界被破坏,后续维护容易出隐蔽 bug - 第三方库接口返回
const T*时,若你确定底层可写且需修改,应先确认文档是否允许,而不是直接强转










