const 是 C/C++ 中「只讀」語義的核心關鍵字,正確使用能顯著提升代碼安全性與可讀性。本文系統梳理 7 大使用場景:變量/指針、函數參數、返回值、對象/指針/引用、成員變量、成員函數、與宏的區別。
const int n = 10; // n 不可變
int const n = 10; // 等價,推薦前者
// 指針場景:沿著 * 看 const 位置
const char *p1; // *p1 不可變(指向常量的指針)
char * const p2; // p2 不可變(常量指針)
const char * const p3; // 雙重不可變
口訣:const 在 * 左 → 修飾指向內容;在 * 右 → 修飾指針本身。
void func(const int val); // 值傳遞,形參本身不可改(意義不大)
void func(const char *str); // 指向內容不可改,防範字符串被修改
void func(char * const ptr); // 指針本身不可改(意義不大)
void func(const MyClass &obj); // 引用參數不可改,避免拷貝且保護數據
引用參數加 const 是「高效+安全」雙贏模式。
const int func1(); // 返回值不可改(內置類型意義小)
const int *func2(); // 返回指向常量的指針,調用者不可修改內容
int * const func3(); // 返回常量指針,調用者不可修改指向
class A {
void func1(); // 非 const
void func2() const; // const 成員函數
};
const A obj;
obj.func1(); // 編譯錯誤
obj.func2(); // 正確
const A *p = new A();
p->func1(); // 錯誤
p->func2(); // 正確
規則:const 對象/指針/引用 只能調用 const 成員函數,因為非 const 成員函數隱含修改成員變量的意圖。
class A {
const int id;
A(int i) : id(i) {} // 必須在初始化列表賦值
};
class A {
void func() const; // 承諾不修改非 mutable 成員,不調用非 const 成員函數
};
mutable 成員(如緩存、鎖計數器)。const。| 維度 | const 常量 | #define 宏 |
|---|---|---|
| 處理階段 | 編譯/運行期 | 預處理期(文本替換) |
| 類型安全 | 有類型,編譯期檢查 | 無類型,純文本展開 |
| 內存佔用 | 分配內存(可取地址) | 不分配,多處展開多份 |
| 調試可見性 | 符號表可見 | 預處理後消失 |
| 作用域 | 遵循作用域規則 | 全局無作用域 |
現代 C++ 建議:優先使用 constexpr(C++11)或 const,完全替代宏常量。
| 場景 | 關鍵點 |
|---|---|
| 指針 | 看 * 左右決定鎖定內容還是指針 |
| 引用參數 | const T& = 高效+安全 |
| 常量對象 | 只能調用 const 成員函數 |
| 成員變量 | 初始化列表賦值,不可變 |
| 成員函數 | 不修改對象狀態,可讀 mutable |
掌握 const 語義邊界,是寫出健壯 C/C++ 代碼的基石。