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

C++ 建構函數參數初始化串列詳解

     編輯:C++ 基礎

為什麼需要初始化串列?

建構函數主體內賦值(m_name = name;)屬於「先預設建構、再指派」,對於 const 成員、參考成員、無預設建構函數的類別成員,**根本無法編譯**。參數初始化串列直接在物件記憶體佈局完成時「一次到位」初始化,語法:

ClassName::ClassName(params) : member1(val1), member2(val2) { /* 體 */ }

基本範例

class Student {
    const char* m_name;
    int m_age;
    float m_score;
public:
    Student(const char* name, int age, float score)
        : m_name(name), m_age(age), m_score(score) { } // 體可為空
    void show() const;
};

等價於主體內三行指派,但更高效(避免預設建構+指派),且支援 const/參考成員。

初始化順序陷阱:宣告順序 ≠ 串列順序

class Demo {
    int m_a;
    int m_b;
public:
    Demo(int b) : m_b(b), m_a(m_b) { } // 串列寫 m_b 在前
    void show() const { cout << m_a << ", " << m_b << endl; }
};

int main() {
    Demo d(100);
    d.show(); // 輸出:垃圾值, 100
}

鐵律:成員初始化順序**嚴格遵循類別內宣告順序**(m_a 先於 m_b),與初始化串列書寫順序無關。上例中 m_a(m_b) 讀取尚未初始化的 m_b,導致 m_a 獲得不定值。
最佳實踐:初始化串列書寫順序與宣告順序保持一致,並開啟編譯器警告(-Wreorder)。

核心用途:初始化 const、參考、無預設建構的成員

class VLA {
    const int m_len;   // const 成員
    int& m_ref;        // 參考成員
    NoDefault m_obj;   // 無預設建構函數的類別成員
public:
    VLA(int len, int& r, const NoDefault& obj)
        : m_len(len), m_ref(r), m_obj(obj) { } // 唯一合法初始化路徑
};

若在建構函數主體指派,編譯器將報錯:「未初始化的 const/參考成員」或「找不到預設建構函數」。

部分成員使用初始化串列

Student::Student(const char* name, int age, float score)
    : m_name(name) { // 僅 m_name 用串列
    m_age = age;     // 其餘在主體指派
    m_score = score;
}

允許混用,但建議統一風格:能用初始化串列盡量用,效率與一致性較佳。

C++11 列表初始化與防窄化

class Widget {
    int m_x;
    double m_y;
public:
    Widget(int x, double y) : m_x{x}, m_y{y} { } // 大括號初始化
};

大括號初始化禁止隱性窄化轉換(double→int、int→char 可能截斷),編譯器將報錯,增強型別安全。

委派建構函數(C++11)

class Student {
    const char* m_name;
    int m_age;
    float m_score;
public:
    Student() : Student("匿名", 0, 0.0f) { } // 委派給三參數版本
    Student(const char* name) : Student(name, 0, 0.0f) { }
    Student(const char* name, int age, float score)
        : m_name(name), m_age(age), m_score(score) { }
};

避免重複初始化邏輯,減少維護負擔。

總結

  • 初始化串列是**唯一**初始化 const、參考、無預設建構成員的合法方式。
  • 初始化順序 = 宣告順序,串列書寫順序應與之對齊。
  • 優於主體指派:避免預設建構+指派開銷,支援更多型別。
  • C++11 大括號初始化防窄化,委派建構函數消除重複碼。

養成「建構函數首選初始化串列」習慣,是高效、安全 C++ 程式碼的基石。

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