mutable 關鍵字用於類的非靜態、非常量數據成員,允許在 const 成員函數(常函數)中修改該成員,解決「邏輯上不變但物理上需修改」的場景。
class Student {
string name;
int nameAccessCount; // 統計名字被訪問次數
public:
Student(const char* n) : name(n), nameAccessCount(0) {}
string getName() {
++nameAccessCount; // 修改計數器
return name;
}
void printAccessCount() const {
cout << nameAccessCount << endl; // 錯誤:const 函數不可修改成員
}
};
int main() {
const Student s("Alice");
s.getName(); // 錯誤:const 對象不可調用非 const 函數
s.printAccessCount(); // 編譯錯誤:const 函數中修改 nameAccessCount
}
class Student {
string name;
mutable int nameAccessCount; // 加上 mutable
public:
Student(const char* n) : name(n), nameAccessCount(0) {}
string getName() const { // 改為 const
++nameAccessCount; // OK:mutable 允許修改
return name;
}
void printAccessCount() const {
cout << nameAccessCount << endl; // OK
}
};
int main() {
const Student s("Alice");
s.getName(); // OK
s.printAccessCount(); // OK,輸出 1
}
| 場景 | 說明 | mutable 成員示例 |
|---|---|---|
| 緩存/備忘錄 | const 方法中緩存計算結果避免重複計算 | mutable int cachedValue; mutable bool cacheValid; |
| 統計/監控 | 調用計數、訪問日誌、性能計時 | mutable int callCount; mutable chrono::time_point lastAccess; |
| 線程同步 | const 方法中加鎖保護共享數據 | mutable mutex mtx; |
| 引用計數 | 智能指針實現中引用計數修改 | mutable int refCount; |
static 成員屬於類而非對象,const 成員本身不可變,均不能用 mutablemutable 成員應為「實現細節」,不影響對象可觀測狀態mutable 表明設計缺陷,應重構分離可變狀態誤區:
mutable讓const對象完全可變。
真相:僅允許修改標記為mutable的特定成員,其他成員仍受const保護。
class DataProcessor {
vector data;
mutable int cachedSum; // 緩存和
mutable bool sumValid; // 緩存有效標誌
public:
DataProcessor(const vector& d) : data(d), cachedSum(0), sumValid(false) {}
int getSum() const {
if (!sumValid) {
cachedSum = accumulate(data.begin(), data.end(), 0);
sumValid = true;
}
return cachedSum;
}
void updateData(const vector& newData) {
data = newData;
sumValid = false; // 非 const 方法中使緩存失效
}
};
mutable 是 C++ 為「邏輯常量性」與「物理可變性」協調提供的機制。正確使用場景:緩存、統計、同步鎖、引用計數等不影響對象外部可觀測行為的內部實現細節。濫用 mutable 會破壞 const 的語義保證,應作為最後手段而非常規手段。