this 指針的隱含類型變化struct SomeType {
int m_a;
void SomeMethod() const { // 錯誤:cannot assign to member 'm_a' within const member function
m_a = 0;
}
};
將隱含的 this 顯式化:
void SomeMethod() const {
this->m_a = 0; // 等價於 const SomeType* const this
}
SomeType* const this (指針常量,指向可修改對象)。const SomeType* const this (指針常量,指向常量對象)。編譯器在 const 成員函數中給 this 加上底層 const,導致無法修改非 mutable 成員。
const?—— 庫版本兼容性危機若 SomeMethod 發布為動態庫 v1.0 (聲明為 const),客戶端代碼如下:
const SomeType obj;
obj.SomeMethod(); // 合法調用 const 成員函數
若 v2.0 為了修改成員去掉 const,客戶端重新編譯時會報錯:passing 'const SomeType' as 'this' argument discards qualifiers。破壞了二進制兼容與源碼兼容。
mutable:專為「邏輯常量」設計的逃生門struct SomeType {
mutable int m_a; // 關鍵字在此
void SomeMethod() const {
m_a = 0; // 編譯通過,運行期可修改
}
};
mutable 告訴編譯器:該成員不影響對象的「可觀測狀態」(Logical State),允許在 const 上下文中修改。典型用例:
mutable int cachedValue;)mutable std::mutex mtx;)const 的三大核心收益const 對象只能調用 const 成員函數。若無 const,const SomeType c; c.method(); 將無法編譯,人為限制了 API 使用範圍。const 讓編譯器假設內存不變,啟用常量傳播、死碼消除、寄存器緩存等優化,提升運行效率。| 場景 | 建議 |
|---|---|
| 不修改任何成員 (含邏輯狀態) | 標記 const |
| 修改「非邏輯狀態」成員 (緩存、鎖、統計) | 成員加 mutable,函數保持 const |
| 必須修改邏輯狀態 | 函數 不加 const |
庫已發布為 const,新版需修改邏輯狀態 | **重構設計** (如分離命令/查詢 CQRS),勿破壞兼容 |
const 與 mutable 並非對立,而是「邏輯常態性」與「物理實現細節」的分離。善用它們,是寫出健壯、高效、可維護 C++ 代碼的關鍵修養。