const是c++类型系统的一部分,修饰“谁不可变”;指针中const就近绑定,成员函数加const才可被const对象调用,constexpr才表示编译期常量。

const 在 C++ 里不是“定义常量的替代品”,而是**类型系统的一部分**,它修饰的是“谁不可变”——这个方向搞错,后面所有用法都会踩坑。
const 修饰指针时,到底谁不能改?
这是最常混淆的点:const 紧贴左边还是右边,决定它约束的对象。没有“固定写法”,只有“就近绑定”规则。
-
int* const p = &x;:指针p本身不可变(不能指向别处),但*p可改 -
const int* p = &x;或int const* p = &x;:*p不可变(不能通过p改x的值),但p可以指向别处 -
const int* const p = &x;:指针和它指向的值都不可变
读法建议从右往左:“p 是 const 指针,指向 const int”——比死记星号位置更可靠。
const 成员函数为什么必须加 const?
不加 const 的成员函数,默认被认为可能修改对象状态,因此无法被 const 对象调用,编译直接报错:error: passing 'const X' as 'this' argument discards qualifiers。
立即学习“C++免费学习笔记(深入)”;
- 加了
const后,编译器会禁止在函数体内修改任何非mutable成员 - 重载时,
const和非const版本可共存,编译器按对象是否为const自动选函数 - 返回
const引用(如const std::string& name() const)能防止调用方意外修改内部数据
const_cast 能否安全去掉 const?
能编译,但绝大多数时候是危险信号——除非你 100% 确定原始对象本身不是 const 定义的。
-
const_cast只去掉类型系统的 const 限定,不改变内存实际可写性 - 对真正 const 对象(如
const int x = 42;)去 const 后写入,是未定义行为(UB),可能崩溃、静默失败或看似正常 - 常见合法场景:封装 C API 时,某个函数参数声明为
const char*,但你传入的却是char*;此时用const_cast是为了满足接口,而非修改数据
constexpr 和 const 到底什么关系?
const 不代表“编译期可知”,constexpr 才是明确要求表达式在编译期求值。
-
const int x = rand();合法(运行期初始化),但不能用于模板非类型参数或数组大小 -
constexpr int y = 42;保证是编译期常量,可用于std::array<int y></int>、switch分支等 - C++14 起,
constexpr函数体内允许有限的运行时逻辑(如if、循环),只要输入是常量,输出仍是编译期常量
把 const 当 constexpr 用,或者以为加了 const 就能当模板参数,是高频误判点。











