const修饰变量时编译器仅在编译期拦截直接赋值,无法阻止const_cast或指针间接修改;成员函数加const约束不能修改非mutable成员及调用非const函数;const引用/指针语义取决于const位置;返回const对象会禁用移动语义。

const 修饰变量时,编译器真会阻止修改吗?
会,但只在直接赋值层面拦截。一旦绕过类型系统(比如用 const_cast),或者通过指针/引用间接操作原始内存,const 就不构成 runtime 防护。
- 编译期检查只针对显式赋值:对
const int x = 5;写x = 10;会报错assignment of read-only variable 'x' - 但
int<em> p = const_cast<int>>(&x); *p = 10;</int></em>在大多数平台能成功(未定义行为,但常“奏效”) - 真正的保护来自语义约束:它告诉调用者“这个值不该变”,也帮编译器做优化(比如把
const int x = 42;当作编译时常量折叠)
成员函数末尾加 const 到底约束什么?
约束的是该函数不能修改 this 指向对象的任何非 mutable 成员,也不得调用非 const 成员函数。
- 常见错误:在
void print() const里写counter++;(counter是普通int成员)→ 编译失败 -
mutable是例外:声明为mutable std::mutex mtx;的成员,可在 const 成员函数中加锁 - 调用链必须全 const:如果
A::foo() const调用了B::bar(),那B::bar()也得是 const 成员函数,否则编译不过
const 引用和 const 指针的区别在哪?
关键看 const 修饰的是“指向的东西”还是“指针本身”,位置决定语义:
-
const int& r = x;:r 绑定后不能通过 r 改x,但x本身仍可被其他途径修改 -
int<em> const p = &x;</em>:p 不能指向别处,但可通过p = 5;修改x -
const int* p = &x;:p 可以指向别处,但不能通过 p 修改所指内容 - 最常见误用:传参写成
void f(int<em> const p)</em>—— 这没意义,因为形参本身就是局部副本,const对调用者无影响;该用void f(const int p)才对
为什么返回 const 对象有时反而阻碍移动语义?
因为 const 会禁用移动构造/赋值——移动操作要求右值引用绑定到非 const 类型。
立即学习“C++免费学习笔记(深入)”;
- 错误示范:
const std::string get_name() { return "Alice"; }
调用auto s = get_name();时,编译器无法调用std::string的移动构造,只能拷贝 - 正确做法:除非有强理由(如防止意外修改返回值),否则不要对按值返回的对象加 const
即用std::string get_name(),而非const std::string get_name() - 特殊情况:返回 const 引用(如
const std::string& name() const)是安全且推荐的,前提是引用的对象生命周期足够长
const 的真正价值不在“防错”,而在表达意图和启用优化。它最易被忽略的点是:一旦加了,就可能悄悄切断移动语义、限制重载匹配、或让模板推导出意外类型——不是所有 const 都值得加,得看上下文是否真需要那份语义承诺。










