const 向编译器表示变量是不可变的(初始化后不能被修改)。用于声明常量变量,以及保证不改变对象状态的方法。
mutable 允许在 const 方法内部修改类字段的值。
volatile 向编译器表示变量的值可能会在程序控制之外(例如由硬件)被修改,编译器不应该优化对其的访问。
class Logger { public: void log() const { ++count; // 允许 — count 被声明为 mutable } private: mutable int count = 0; }; volatile int flag; void wait() { while (flag == 0) { /* 编译器不优化循环,因为 flag 是 volatile */ } }
«如果将类成员同时声明为
const和mutable会发生什么?」
答案: 这样做是不允许的,这是互斥的修饰符;编译器会报错。
故事
在工业软件中处理硬件时,开发者把由外部中断更新的数据声明为普通的 int。编译器的优化去掉了对这些变量的重复读取,导致程序在无限循环中“挂起”。问题仅在替换为
volatile int后得以诊断。
故事
一个日志类有
log() const方法,需要更新调用计数器。最初通过const_cast指针实现,这引发了大量警告和不明显的错误。在正确使用mutable声明计数器后,问题得以解决。
故事
某些类的方法被声明为
const,但指针类型的成员被修改(例如为了实现缓存)。这导致了“const-correctness”的逻辑破坏,甚至在对象实际上放置在只读区域时导致 UB。应该使用mutable或更改设计。