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

Effective C++ 條款 04:確保物件在使用前已初始化

     編輯:關於C++

核心觀念

C++ 不保證內建型別(int、指標等)在定義時自動初始化。使用未初始化物件屬於未定義行為,極難除錯。務必在物件建立時完成初始化。

三大初始化策略

1. 手動初始化內建型別

int x = 0;        // 定義即初始化
int* p = nullptr; // 指標初始化為空
double d = 3.14;

養成「定義即初始化」習慣,避免分離宣告與賦值。

2. 使用成員初始化列表初始化類別成員

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 成員、無預設建構函式的成員、基底類別建構必須在初始化列表完成。

初始化順序固定為類別聲明順序,與初始化列表書寫順序無關。請依聲明順序撰寫列表,避免相依性導致的微妙錯誤。

3. 解決跨編譯單元 non-local static 物件初始化順序問題

問題:不同 .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 已初始化
  • 函式區域 static 物件在首次呼叫函式時初始化(C++11 保證執行緒安全)。
  • 將 non-local static 包裝在存取函式中,轉為 local static,消除跨檔初始化順序相依。

總結

  • 內建型別:定義時初始化。
  • 類別成員:使用成員初始化列表,按聲明順序。
  • 跨檔 static 物件:改用函式區域 static(Singleton)延遲初始化至首次使用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved