在 C++ 中,mutable 的中文含義是「可變的、易變的」,它與 const 恰好相反。這個關鍵字的存在,正是為了突破 const 的限制:被 mutable 修飾的成員變量,永遠處於可變狀態,即使在 const 成員函數中也能被修改。
當類的成員函數不會改變對象的邏輯狀態時,我們通常將其聲明為 const。然而,有時候我們需要在 const 函數內部修改某些與對象「邏輯狀態」無關的數據成員——例如統計計數器、緩存標記、鎖變量等。若直接移除函數的 const 資格,會破壞接口的語義;這時 mutable 便是最佳解決方案。
假設有一個類 ClxTest,其 Output() 函數僅負責輸出文本,不修改對象狀態,故聲明為 const。外部函數 OutputTest 接收 const ClxTest& 參數,確保不會意外修改對象。
class ClxTest {
public:
void Output() const;
};
void ClxTest::Output() const {
cout << "Output for test!" << endl;
}
void OutputTest(const ClxTest& lx) {
lx.Output();
}
現在需求變更:要統計每個對象的 Output() 調用次數。若用普通成員變量 int m_iTimes,在 const 函數中無法修改;若為此移除 const,又違背設計初衷。解決之道:將計數器聲明為 mutable。
class ClxTest {
public:
ClxTest();
~ClxTest();
void Output() const;
int GetOutputTimes() const;
private:
mutable int m_iTimes; // 突破 const 限制
};
ClxTest::ClxTest() : m_iTimes(0) {}
ClxTest::~ClxTest() {}
void ClxTest::Output() const {
cout << "Output for test!" << endl;
++m_iTimes; // 在 const 函數中修改 mutable 成員
}
int ClxTest::GetOutputTimes() const {
return m_iTimes;
}
void OutputTest(const ClxTest& lx) {
cout << lx.GetOutputTimes() << endl;
lx.Output();
cout << lx.GetOutputTimes() << endl;
}
mutable 僅能修飾類的**非靜態數據成員**;const 成員函數修改該成員;mutable 會削弱 const 的語義保證,應謹慎使用。善用 mutable,能在保持接口語義純淨的同時,靈活處理內部輔助性狀態,是 C++ 進階編程的重要技巧之一。