| 特性 | 文字常量 | 常變量 (const) |
|---|---|---|
| 存儲區 | 代碼區(不可尋址) | 數據區(可尋址) |
| 值可變性 | 不可變 | 語法層面不可變,運行期可通過指針修改 |
| 例子 | 靜態數組名、枚舉值、#define、字符串字面值 | const int x = 5; |
初始化的 const 整型變量,編譯器視為編譯期常量,在用處替換為文字常量:
const int m = 5;
int arr[m]; // OK:m 被替換為 5
const int n; // 未初始化
// int arr2[n]; // 錯誤:n 非常量表達式
int const* p1; // const int* p1:指向常量的指針,*p1 不可改,p1 可改
int* const p2; // 指針常量,p2 不可改,*p2 可改
int const* const p3; // 兩者皆不可改
記憶口訣:const 修飾右側實體。int const* → 修飾 int;int* const → 修飾 int*。
int const** p1; // 指向「指向常量的指針」的指針
int* const* p2; // 指向「指針常量」的指針
const int& r = 5;:綁定臨時對象,延長生命周期int& const r = x;:無意義,引用本身不可重綁定,編譯器忽略const ClassName obj; → 所有非靜態成員視為 const,只能調用常函數。
class A {
int num;
public:
void disp() const { cout << num << endl; } // 承諾不修改成員
void set(int n) { num = n; } // 非常函數
};
規則:
constconst 參與函數簽名 → 可重載:void f(); void f() const;(const A&)obj.f() 或 static_cast(obj).f() | 位置 | 作用 | 建議 |
|---|---|---|
值參數 void f(const int x) | 無實質意義,不影響調用端 | 不加 |
引用參數 void f(const int& x) | 防止函數內修改實參,接受臨時對象 | 推薦用於大對象輸入參數 |
指針參數 void f(const int* p) | 防止通過指針修改目標 | 推薦 |
返回值 const int f() | 返回非引用類型無意義(右值不可改) | 不加 |
返回引用 const int& f() | 防止 f() = 10; 修改被引用對象 | 必要時加 |
去除 const/volatile 資格:
const int a = 5;
int& r = const_cast(a); // OK:去除引用的 const
++r; // 運行期修改成功(但未定義行為風險)
// 錯誤用法:
// int b = const_cast(a); // 僅能轉換指針/引用類型
// char* p = const_cast(&a); // 不能改變底層類型
const_cast(expression) ,括號不可省const T*→T* 或 const T&→T&const 屬性(如 const int a 本身仍是只讀內存)誤區 1:
const變量絕對不可修改。
真相:語法層面保護,運行期可通過指針繞過(未定義行為)。誤區 2:常引用/指針只能指向常量。
真相:常引用可綁定非常量對象,僅限制「通過該引用/指針修改」。
const 是 C++ 類型系統的核心組件,提供編譯期不可變性承諾。掌握要點:
const 修飾右側實體(指針/引用/類型)const T& 避免拷貝且保護實參const_cast 僅用於接舊式非 const API,屬最後手段