以下四種情況只能在初始化列表中完成,無法在構造函數體內賦值:
// 低效寫法:構造函數體內賦值
class Word {
String _name;
int _cnt;
public:
Word() { _name = 0; _cnt = 0; } // 產生臨時對象、拷貝、銷毀
};
// 高效寫法:初始化列表
Word::Word() : _name(0) { _cnt = 0; } // 直接調用 String(int) 構造
編譯器會將初始化列表展開為構造函數體開頭的成員構造調用,避免預設構造 + 賦值 + 析構的額外開銷。
成員初始化順序由類中聲明順序決定,而非初始化列表中的書寫順序。
class X {
int i;
int j;
public:
X(int val) : j(val), i(j) {} // 危險!i 先初始化,但 j 尚未賦值
};
上例中 i 會被初始化為不可預測的垃圾值。編譯器應發出警告(如 g++),但 MSVC 可能不警告。
X(int val) : j(val) { i = j; } 是安全的,因為 j 的初始化先於 i = j。合法,因為 this 指針已就緒。但建議謹慎使用,避免依賴尚未初始化的其他成員。
X::X(int val) : i(xfoo(val)), j(val) {} // xfoo 為成員函數
// 展開為:i = this->xfoo(val); j = val;