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

Effective C++ 條款 13:成員初始化順序與宣告順序一致的深層原因

     編輯:程式設計綜合問答

條款內容回顧

「成員初始化順序永遠遵循類別宣告順序,而非初始化列表書寫順序。」

經典反例

class A {
    int sum1;
    int sum2;
public:
    A() : sum2(sum1), sum1(10) {}  // 危險:sum2 使用未初始化的 sum1
};

此處 sum2 會獲得隨機垃圾值,因 sum1 宣告在前但初始化在後。

為何 sum2(10), sum1(10) 沒問題?

A() : sum2(10), sum1(10) {}  // 安全:sum2 不依賴 sum1

兩成員皆以字面常數初始化,無相依關係,故順序無影響。

編譯器實作機制

  1. 解析初始化列表,建立「成員→初始化運算式」對應表
  2. 按類別宣告順序依序產生初始化程式碼
  3. 忽略初始化列表中的書寫順序

這設計確保:

  • 基類先於衍生類初始化
  • 成員按記憶體佈局順序初始化,利於最佳化
  • 解構順序嚴格相反,保證資源正確釋放

最佳實踐

  1. 初始化列表書寫順序 = 宣告順序,避免認知負擔
  2. 避免成員間相依初始化,若必要,改用建構函式本體賦值
  3. 啟用編譯器警告 -Wreorder (GCC/Clang) 或 /Wall (MSVC) 自動檢測
  4. 使用 clang-tidy cppcoreguidelines-avoid-member-init-order 靜態分析

進階:委派建構函式 (C++11)


class A {
    int sum1, sum2;
    A(int v) : sum1(v), sum2(v) {}  // 共同邏輯集中
public:
    A() : A(10) {}  // 委派給私有建構函式
};
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved