核心口訣:const 修飾右側實體 (讀法由右向左)。
int b = 500;
const int* a1 = &b; // a1 是指標,指向 const int (資料不可改)
int const* a2 = &b; // 同上,寫法等價
int* const a3 = &b; // a3 是 const 指標 (指標本身不可改),資料可改
const int* const a4 = &b; // 指標與資料皆不可改
| 宣告 | 指標可改? | 資料可改? | 典型用途 |
|---|---|---|---|
| const int* p | 是 | 否 | 函數參數防修改、只讀檢視 |
| int* const p | 否 | 是 | 固定指向特定緩衝區/硬體暫存器 |
| const int* const p | 否 | 否 | 常數表格、不可變配置 |
A b;
const A a = b; // 複製建構,a 為不可變副本
A* d = new A();
const A* c = d; // 非 const 指標 → const 指標 (安全:加強限制)
const A* c2 = new A(); // 直接建構 const 物件
A f;
const A& e = f; // 綁定 const 引用,e 只能呼叫 const 成員函數
// Q1: const int* c = new int(10); int* e = c; // 錯誤:const → non-const 降低限制
// Q2: int* const c = new int(10); int* b = c; // 合法:複製指標值,b 可改資料
void func(const BigObject& obj); // 避免拷貝,承諾不修改
void func(const BigObject* ptr); // 同理
// 回傳 const 物件 (by value) - 防止 (a+b)=c 這類無意義賦值
const Rational operator*(const Rational&, const Rational&);
// 回傳 const 引用/指標 - 保護內部狀態
const BigObject& getInstance() const;
class MyClass {
mutable int cache_; // 可變快取
int data_;
public:
int getData() const { return data_; } // 承諾不修改 data_
void setData(int v) { data_ = v; } // 非 const
int expensiveCalc() const { // const 函數可修改 mutable
if (!cached_) { cache_ = compute(); cached_=true; }
return cache_;
}
};
const 成員函數中 this 型別為 const MyClass*,無法修改非 mutable 成員。const 物件只能呼叫 const 成員函數;非 const 物件優先呼叫非 const 版本。
class Base { virtual void foo() const = 0; };
class Derived : public Base {
void foo() const override { /* ... */ } // 必須保持 const
};
const int* cp = &x;
int* np = const_cast(cp); // 僅用於介接無 const 正確性的舊 API,極度謹慎
const A& bad() { A tmp; return tmp; } // 錯誤:懸空引用
A good() { return A(); } // C++17 RVO/NRVO 直接回傳物件
const T&;小型型別 (int, 指標) 直接 T。(a+b)=c 這類運算子重載場景。const_iterator / cbegin() / cend()。std::shared_ptr 表達不可變共享所有權。constexpr:編譯期常數,強於 const (隱含 const)。constinit (C++20):確保靜態儲存期變數靜態初始化。std::as_const(obj) (C++17):取得 const 左值引用,強制呼叫 const 多型。auto [x, y] = func(); 配合 const auto&。const 不只是關鍵字,更是 C++ 型別系統表達「不可變性」的核心工具。從指標語義、參數傳遞、成員函數契約到現代 constexpr,貫徹 const 正確性能讓程式碼更安全、可讀、可優化。養成「預設一切皆 const,除非需要修改」的習慣,是資深 C++ 開發者的標誌。