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
};
const、參考型別、無預設建構函式的成員**必須**在列表初始化。-Wreorder / /Wall)可自動偵測順序不符。理解初始化順序規則,能避免難以除錯的未定義行為,撰寫更健壯的 C++ 程式碼。