const变量必须初始化,否则编译错误;const成员函数不可修改非mutable成员;mutable是唯一例外;const指针与指针const需区分;const_cast仅用于原始对象非常量的场景。
声明 const 变量不初始化是编译错误,因为它的值在生命周期内不可变。哪怕后续用函数返回值赋值也不行——必须在定义时就给定确定的值。
const int MAX_SIZE = 100;
const int MAX_SIZE; MAX_SIZE = 100; // 编译失败:assignment of read-only variable
const 引用或指针,初始化目标也必须是可访问的左值(比如不能绑定到临时对象,除非是 const T& 延长生命周期的特例)在类成员函数声明末尾加 const,表示该函数承诺不修改任何非 mutable 成员。编译器会检查所有赋值、调用非常量成员函数等操作。
count++ 或调用了 update_cache()(而它没声明为 const),编译直接报错mutable 是唯一例外:它允许在 const 成员函数中修改,常用于缓存、日志计数等不影响逻辑状态的字段class Counter {
mutable int cache_hit_;
int value_;
public:
int get_cached() const {
cache_hit_++; // ✅ 允许:cache_hit_ 是 mutable
return value_; // ✅ 不修改 value_
}
void set_value(int v) { value_ = v; } // ❌ 不能在 const 函数里调用
};读法从右往左:“T const*” 是“指向常量 T 的指针”,“T* const” 是“常量指针,指向 T”。混淆会导致意外交互错误,尤其在函数参数传递时。
const int* p 或 int const* p:指针可变,指向内容不可变 → 适合只读遍历数组int* const p = &x;:指针不可变(绑定后不能指向别处),内容可变 → 常用于封装资源句柄const int* const p = &x;:两者都不可变 → 多见于全局配置指针const std::string& s 比传 std::string const* s 更安全简洁,避免空指针和所有权歧义const_cast 只应在与 C API 交互等极少数场景下使用,且前提是原始对象本身**不是 const 定义的**。对真正 const 的对象强制修改,行为未定义。
立即学习“C++免费学习笔记(深入)”;
void c_api_func(char* buffer); // C 接口不支持 const std::string s = "hello"; c_api_func(const_cast(s.data())); // s 本身非常量,安全
const std::string cs = "hello"; c_api_func(const_cast(cs.data())); // 未定义行为:修改 const 对象
std::string_view 接收只读字符串,或设计接口接受 const char*,而非依赖 const_cast
const 的价值不在语法装饰,而在让编译器帮你守住契约边界。最容易被忽略的是:把参数声明为 const T& 不仅避免拷贝,还明确表达了“我不会改你”,这比注释可靠得多。