看到 const,C++ 程式設計師常只想到常數。若僅用於定義常數,如同「只用火藥造鞭炮」。const 更大的魅力在於修飾**函式參數、回傳值、甚至函式定義體**。被 const 修飾的東西受強制保護,預防意外變動,大幅提升程式健壯性。眾多 C++ 經典著作建議:「Use const whenever you need」。
鐵律:輸出參數絕不可加 const,否則喪失輸出功能。const 只能修飾輸入參數:
加 const 防止意外修改指標指向內容,起保護作用。
void StringCopy(char* strDestination, const char* strSource);
// strSource 為輸入參數,strDestination 為輸出參數
// 函式體嘗試修改 strSource 內容 → 編譯錯誤
函式會自動產生暫時變數複製參數,原參數本就無需保護,**勿加 const**。
// 不要寫成
void Func1(const int x);
void Func2(const A a); // A 為使用者自訂型別
void Func(A a) 效率低:產生暫時物件(建構+複製+解構)。改為 void Func(A& a) 避免暫時物件,但參考可能修改參數。解決:加 const → void Func(const A& a)。
完全沒必要。內建型別無建構/解構,複製極快,傳值與傳參考效率幾乎相同。改用 const int& 反而降低可讀性。
| 參數型別 | 傳遞方式 | 建議 |
|---|---|---|
| 非內建型別 | 傳值 | 改為 const A& 提升效率 |
| 內建型別 | 傳值 | 保持傳值,勿改 const int& |
| 指標 | 指標傳遞 | 加 const 修飾指向內容(const char*) |
const 的同型別指標。
const char* GetString();
// char* str = GetString(); // 編譯錯誤
const char* str = GetString(); // 正確
const int GetInt()、const A GetA() 皆無意義。const A& GetA() 確能提升效率,但**必須極度小心**:搞清楚是要回傳物件「拷貝」還是僅「別名」,否則出錯。詳見 6.2 節。
class A { A& operator=(const A& other); };
A a, b, c;
a = b = c; // 正常鏈式
(a = b) = c; // 異常但合法
若指派運算子回傳值加 const,(a = b) = c 變非法(回傳值不可修改)。