首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 建構函式初始化列表成員初始化順序陷阱

     編輯:程式設計綜合問答

程式碼比較

class A {
    int n1, n2;
public:
    // 寫法一:建構函式本體賦值
    A() {
        n2 = 0;
        n1 = n2 + 2; // n1=2, n2=0
    }

    // 寫法二:初始化列表
    A() : n2(0), n1(n2 + 2) {} // n1=-858993458 (亂碼), n2=0
};

核心規則

成員初始化順序遵循「類別定義中的宣告順序」,而非初始化列表的書寫順序。

上例中 n1 宣告在 n2 之前,因此初始化時 n1 先執行,此時 n2 尚未初始化(亂碼),導致 n1 = n2 + 2 運算錯誤。

正確寫法

class A {
    int n1, n2; // 宣告順序:n1, n2
public:
    // 選項 1:調整宣告順序
    // int n2, n1; // n2 先宣告,再 n1

    // 選項 2:初始化列表順序配合宣告順序,且不相依未初始化成員
    A() : n1(2), n2(0) {} // 直接給定值,不相依

    // 選項 3:若 n1 需根據 n2 計算,需將 n2 宣告在前
    // int n2, n1;
    // A() : n2(0), n1(n2 + 2) {} // 正確:n2=0, n1=2
};

最佳實務建議

  1. 初始化列表書寫順序與成員宣告順序保持一致,降低認知負擔。
  2. 避免在初始化列表中使用其他成員未初始化的值。
  3. 優先使用初始化列表而非建構函式本體賦值:效率較高(避免預設建構後再賦值),且 const、參考型別、無預設建構函式的成員**必須**在列表初始化。
  4. 啟用編譯器警告(-Wreorder / /Wall)可自動偵測順序不符。

延伸:基底類別與成員初始化順序

  1. 基底類別建構函式(按繼承順序)
  2. 非靜態成員變數(按宣告順序)
  3. 建構函式本體

理解初始化順序規則,能避免難以除錯的未定義行為,撰寫更健壯的 C++ 程式碼。

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