C++ 不保證內建型別(int、指標等)在定義時自動初始化。使用未初始化物件屬於未定義行為,極難除錯。務必在物件建立時完成初始化。
int x = 0; // 定義即初始化
int* p = nullptr; // 指標初始化為空
double d = 3.14;
養成「定義即初始化」習慣,避免分離宣告與賦值。
class Customer {
std::string name;
std::string address;
PhoneNumber phone;
int usedTimes;
public:
// ✅ 正確:成員初始化列表
Customer(const std::string& n, const std::string& a, const PhoneNumber& p)
: name(n), address(a), phone(p), usedTimes(0) {}
// ❌ 錯誤:建構函式本體內賦值
// Customer(...) { name = n; ... } // 先 default-construct 再 assign,雙重開銷
};
優點:避免「先預設建構、再指派」的額外開銷;必要條件:const/reference 成員、無預設建構函式的成員、基底類別建構必須在初始化列表完成。
初始化順序固定為類別聲明順序,與初始化列表書寫順序無關。請依聲明順序撰寫列表,避免相依性導致的微妙錯誤。
問題:不同 .cpp 檔的 non-local static 物件(全域/命名空間/類別 static 成員)初始化順序未定義。若 A.cpp 的物件依賴 B.cpp 的物件,可能在 B 尚未初始化時被使用。
解法:Singleton 模式 / 函式區域 static
// A.cpp
class FileSystem { /* ... */ };
FileSystem& getFileSystem() {
static FileSystem fs; // 函式區域 static:首次呼叫時初始化
return fs;
}
// B.cpp 使用
void foo() { getFileSystem().read(...); } // 確保 fs 已初始化