const变量必须初始化,未初始化将编译报错;其修饰指针时位置决定保护对象;const成员函数承诺不修改对象状态;const不等价于constexpr,后者要求编译期可求值。

const 变量定义必须初始化
不初始化的 const 变量在编译期直接报错,比如 const int x; 会触发 error: uninitialized const 'x'。C++ 要求所有 const 对象在声明时就必须有确定值,因为之后不能再赋值。
- 全局或命名空间作用域的
const变量默认是内部链接(internal linkage),想跨文件用得加extern - 局部
const变量可以是运行时初始化(如const int y = rand();),但仍是只读的 - 若用于数组大小、模板非类型参数等编译期常量场景,必须是字面量或
constexpr表达式,仅const不够
const 修饰指针:三种写法对应三种含义
const 在指针声明里的位置决定它管的是“指针本身”还是“指针指向的内容”,容易混淆。
-
const int* p;或int const* p;:指针可变,内容不可变(常量数据) -
int* const p = &x;:指针不可变(必须初始化),内容可变 -
const int* const p = &x;:指针和内容都不可变
记忆口诀:const 紧挨谁,就保护谁;从右往左读更稳(如 int const * const p → “p 是 const 指针,指向 const int”)。
const 成员函数不能修改对象状态
类成员函数加 const 后缀,表示承诺不修改 *this 的任何非 mutable 成员。否则编译器拒绝调用,比如:
立即学习“C++免费学习笔记(深入)”;
class Widget {
int cache_;
mutable int call_count_; // 允许在 const 函数里改
public:
int get() const {
++call_count_; // OK
// cache_ = 42; // error: assignment to member 'cache_' in readonly object
return cache_;
}
};- 非常量对象可以调用 const 和非 const 版本;const 对象只能调用 const 成员函数
- 重载时,const 与非 const 版本可共存,构成不同签名(如
operator[]常见这种设计) - 返回引用时,const 成员函数应返回
const T&,避免破坏只读性
const 和 constexpr 不是替代关系
const 描述运行时不可变性,constexpr 要求编译期可求值。很多地方只写 const 是不够的。
- 数组长度、模板参数、
case标签值等需要编译期常量,必须用constexpr(或字面量) -
const int x = 10;是 const,但也是编译期常量;const int y = rand();是 const,但不是 constexpr - C++17 起,
static constexpr是定义类内整型常量的标准方式,比static const更明确、更安全
真正复杂的地方在于:const 对象的生命周期、线程间可见性、以及和 volatile 的交互——这些在嵌入式或并发场景下才露头,日常写业务代码时,先盯紧初始化和指针修饰这两关就够了。











