首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ const 關鍵字完全指南:從基礎語法到進階最佳實務

     編輯:關於C++

一、const 基礎:指標與引用的雙重語義

核心口訣: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否否常數表格、不可變配置

二、const 初始化規則

非指標型別


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 可改資料

三、函數參數與回傳值的 const

1. 參數 const (傳遞大型物件時必加)


void func(const BigObject& obj); // 避免拷貝,承諾不修改
void func(const BigObject* ptr); // 同理

2. 回傳值 const


// 回傳 const 物件 (by value) - 防止 (a+b)=c 這類無意義賦值
const Rational operator*(const Rational&, const Rational&);

// 回傳 const 引用/指標 - 保護內部狀態
const BigObject& getInstance() const;

3. 成員函數 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 版本。

四、進階技巧與陷阱

1. const 與多型


class Base { virtual void foo() const = 0; };
class Derived : public Base {
    void foo() const override { /* ... */ } // 必須保持 const
};

2. const 轉型


const int* cp = &x;
int* np = const_cast(cp); // 僅用於介接無 const 正確性的舊 API,極度謹慎

3. 避免回傳 const 區域物件參考


const A& bad() { A tmp; return tmp; } // 錯誤:懸空引用
A good() { return A(); } // C++17 RVO/NRVO 直接回傳物件

五、實務建議總結 (Effective C++ 風格)

  1. 大膽使用 const:讓編譯器幫你找 Bug,文件化介面契約。
  2. 參數傳遞:大型物件用 const T&;小型型別 (int, 指標) 直接 T。
  3. 成員函數:凡不修改觀測狀態者,必加 const。
  4. 回傳值:少用 const 修飾回傳值型別 (C++11 移動語意下阻礙優化),除非為防止 (a+b)=c 這類運算子重載場景。
  5. 迭代器:優先使用 const_iterator / cbegin() / cend()。
  6. 智慧指標:std::shared_ptr 表達不可變共享所有權。

六、現代 C++ (C++11/14/17/20) 新特性

  • 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++ 開發者的標誌。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved