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

C++ 類別與 const 關鍵字深度解析

     編輯:C++ 基礎

前言

在 C++ 類別設計中,若希望特定資料成員或成員函數不可被修改,const 關鍵字是不可或缺的工具。它可修飾成員變數、成員函數乃至整個物件,提供編譯期的安全保障。本文將系統性探討 const 在類別中的三大核心應用場景。

一、const 成員變數:不可變的資料成員

const 成員變數的宣告語法與一般 const 變數相同,僅需在型別前加上關鍵字。關鍵差別在於初始化方式:唯有透過建構函數的參數初始化串列 才能賦值,因為 const 成員不可在建構函數主體內透過指派運算子初始化。

class Student {
public:
    Student(const char* name, int age, float score);
private:
    const char* m_name; // const 成員變數
    int m_age;
    float m_score;
};

// 必須使用初始化串列
Student::Student(const char* name, int age, float score)
    : m_name(name), m_age(age), m_score(score) { }

若嘗試在建構函數主體內賦值(m_name = name;),編譯器將報錯。這機制確保了 const 成員自物件出生起即擁有確定值,且終生不可更改。

二、const 成員函數:承諾不修改物件狀態

被 const 修飾的成員函數稱為「常成員函數」。其核心規則:可讀取任意成員變數,但不可修改非 mutable 成員。這為呼叫端提供強烈語義保證——呼叫此函數不會改變物件可觀測狀態。

語法規範

宣告與定義處皆須在參數列表後加上 const:

class Student {
public:
    char* getName() const; // 宣告
    int getAge() const;
    float getScore() const;
};

// 定義時同樣需要 const
char* Student::getName() const { return m_name; }
int Student::getAge() const { return m_age; }
float Student::getScore() const { return m_score; }

常見錯誤:僅在宣告或定義單處加 const 會導致函數原型不匹配,因為 char* getName() const 與 char* getName() 是兩個不同簽章。

設計原則

凡「唯讀」操作(getter、查詢、顯示等)皆應標記 const。這不僅是防呆,更讓介面語義清晰:呼叫端一眼即知該操作安全無副作用。

三、const 物件:唯讀的實體

以 const 修飾物件(或指向物件的指標),得到「常物件」。其核心限制:常物件僅能呼叫 const 成員函數、存取 const 成員變數。編譯器假設非 const 成員可能修改資料,故禁止常物件存取。

宣告形式

const Student stu("小明", 15, 90.6);           // 常物件
Student const stu2("李華", 16, 85.0);          // 等效寫法
const Student* pStu = new Student("王五", 17, 88.5); // 常物件指標

實戰範例

int main() {
    const Student stu("小明", 15, 90.6);
    // stu.show();       // 錯誤:show() 非 const
    cout << stu.getName() << " 年齡 " << stu.getAge() << " 成績 " << stu.getScore() << endl;

    const Student* pStu = new Student("李磊", 16, 80.5);
    // pStu->show();     // 錯誤
    cout << pStu->getName() << " 年齡 " << pStu->getAge() << " 成績 " << pStu->getScore() << endl;
    delete pStu;
    return 0;
}

若 show() 亦標記 const,常物件即可呼叫。良好的實踐是:凡不修改狀態的公開介面,一律加 const。

四、進階議題:mutable 與邏輯常態

極少數情況下,const 成員函數確需修改某些不影響物件「邏輯狀態」的資料(如快取、鎖、統計計數器)。此時可將該成員標記 mutable:

class Cache {
public:
    int getValue() const {
        if (!m_cached) { m_value = compute(); m_cached = true; }
        return m_value;
    }
private:
    mutable int m_value;
    mutable bool m_cached = false;
};

mutable 打破了位元常態,保留了邏輯常態,屬進階技巧,慎用。

總結

  • const 成員變數:唯一初始化路徑為建構函數初始化串列,保證不可變性。
  • const 成員函數:宣告與定義雙雙加 const,承諾不修改非 mutable 成員,強化介面契約。
  • const 物件:僅能存取 const 成員,倒逼類別設計者將唯讀操作標記為 const。
  • 最佳實踐:預設所有不修改狀態的公開函數皆加 const,除非確有修改需求。

善用 const 能在編譯期捕捉大量邏輯錯誤,是 C++ 型別系統賦予開發者的強大防禦機制,請養成「預設加 const,非必要不移除」的習慣。

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