const 告訴編譯器:「我不會通過這個符號修改該值」。編譯器以此進行靜態檢查,但不保證運行時只讀(可通過指針轉換、硬體映射等繞過)。
const int n = 10; // n 為只讀,編譯期常量傳播優化 // n = 20; // 編譯錯誤:賦值只讀變量 int arr[n]; // C99 支持 VLA,但 C89/C++ 標準不允許作數組長度(需常量表達式)
const int 默認內部連接,可直接作數組長度、模板參數;C 中需配合 #define 或 enum。volatile:volatile const int *port = (void*)0x4000;(硬體只讀寄存器)。const int *p1; // p1 可變,*p1 只讀(指向常量的指針) int const *p2; // 同 p1,const 修飾左側 int int *const p3; // p3 只讀,*p3 可讀寫(常量指針) const int *const p4; // p4 只讀,*p4 只讀(雙重鎖定)
const 在 * 左側 → 修飾 *p(指向的值只讀)。const 在 * 右側 → 修飾 p(指針本身只讀)。const char *str = "hello"; 字符串字面值區只讀,防止誤寫。int *const ptr = &var; 固定指針指向,防止指針漂移。void foo(const int *arr, int n); // 承諾:不修改 arr 指向的內容 void bar(const MyStruct *ctx); // 承諾:不修改 ctx 內部狀態
const int *const p 同時鎖定指針與內容,最嚴格契約。const 只約束「通過此符號訪問」,若實參實際指向可寫內存,函數內部仍可通過強制類型轉換修改(const_cast / C 風格轉換),屬於違約行為。const int foo(); // 返回基本類型:無意義,臨時值本不可賦值 const MyStruct bar(); // 返回結構體:防止 bar().member = val 這類誤操作 const MyStruct& baz(); // 返回引用:極其重要,防止修改被引用對象(如單例、緩存)
const:C++ 標準建議不要加,無實際意義且干擾移動語義優化(C++11 起)。const:有意義,保護對象內部狀態。const:核心用法,實現「只讀訪問」語義(如 const vector& getData() const)。| 轉換方向 | 是否允許 | 原因 |
|---|---|---|
T* → const T* | ✅ 隱式允許 | 增加約束,安全 |
const T* → T* | ❌ 隱式禁止 | 移除約束,危險(需 const_cast) |
T** → const T** | ❌ 禁止 | 間接修改風險:const T** p; *p = &const_obj; **p = val; |
T* const* → const T* const* | ✅ 允許 | 指針本身已鎖定,安全 |
void foo() const)默認加 const。void func(const int *const p) 同時保護指針與數據。volatile const、多線程共享只讀標誌 volatile const(配合原子操作)。constexpr,語義更強、優化更激進。const 是 C/C++ 類型系統中「只讀語義」的基石。從變量定義到指針層級鎖定,再到函數接口契約與返回值保護,const 構建了層層遞進的防禦體系。將 const 內化為「默認加、漏加即缺陷」的肌肉記憶,是寫出健壯、可維護、可優化代碼的關鍵習慣。