const 是 **cv-qualifier(類型限定符)**,修飾其**右側最近的類型實體**(左結合)。讀法:從右向左讀,const int* p → `p is a pointer to const int`。
const int MAX = 100; // 編譯期常量,符號表存儲,無內存分配 const double PI = 3.14159; // 類同 // 優於 #define:有類型、作用域、可調試、不污染宏命名空間
| 聲明 | 含義 | 可修改指針 | 可修改指向值 |
|---|---|---|---|
const int* p / int const* p | 指向常量的指針 | ✅ | ❌ |
int* const p | 常量指針 | ❌ | ✅ |
const int* const p | 指向常量的常量指針 | ❌ | ❌ |
int const* const p | 同上(等價) | ❌ | ❌ |
int a = 10, b = 20; const int* p1 = &a; // ok // *p1 = 20; // error p1 = &b; // ok int* const p2 = &a; // 初始化必賦值 *p2 = 30; // ok // p2 = &b; // error
const int& ref = a; // 常量引用,綁定臨時對象延長生命周期 // int& ref2 = 10; // error:非常量引用不能綁定右值 const int& ref3 = 10; // ok:創建臨時 int(10),ref3 綁定,壽命延長至作用域結束
void func(const BigObject& obj); // 推薦:避免拷貝,保護數據 void func(const BigObject* ptr); // 同理 const BigObject& getRef(); // 返回常量引用,防止修改內部狀態 BigObject getVal(); // 返回值,C++17 RVO/NRVO 消除拷貝
class Widget {
int value;
public:
int getValue() const { return value; } // 常量成員函數
// void setValue(int v) const { value = v; } // error:不能修改非 mutable 成員
mutable int cacheHits; // 邏輯常態下可修改
int getCacheHits() const { return ++cacheHits; } // ok
// 重載:const/非雙版本
const int& operator[](size_t i) const { return data[i]; }
int& operator[](size_t i) { return data[i]; }
private:
std::vector data;
};
規則:const 成員函數隱含 `const Widget* const this`,不可修改非 mutable 成員,不可調用非常量成員函數。
class Config {
static const int MAX_CONN = 100; // C++11 類內初始化(整型)
static const double TIMEOUT; // 非常量/浮點需類外定義
static constexpr int VERSION = 1; // C++11 constexpr 隱含 static
};
// 類外定義(C++17 前必須)
const double Config::TIMEOUT = 30.0;
// C++17 inline static 可類內定義
inline static const std::string DEFAULT_HOST = "localhost";
templatestruct Foo {}; // 指針模板參數需外部鏈接 const int VAL = 42; Foo<&VAL> f; // ok // C++20 概念與 auto 參數 template struct Bar {}; Bar<42> b; // 自動推導類型
const int ci = 10; int* p = const_cast(&ci); // *p = 20; // 未定義行為:修改原本 const 對象 // 合法場景:調用無 const 正確性的舊 API void legacy_api(char* buf); // 不修改 buf 但未標 const void safe_wrapper(const std::string& s) { legacy_api(const_cast (s.c_str())); // 承諾不修改 }
| 特性 | const | constexpr |
|---|---|---|
| 求值時機 | 運行時(可能編譯期) | **保證編譯期** |
| 函數 | 不可 | 可(C++11 受限,C++14 放寬) |
| 構造函數 | 不可 | 可(字面類型) |
| 用作數組長度/模板參數 | 不一定 | ✅ |