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

《深度探索 C++ 物件模型》讀書筆記(3):資料成員佈局、繼承與虛繼承大小計算

     編輯:關於C++

VC6 實測類別大小

class X {};                    // 1
class Y : public virtual X {}; // 4
class Z : public virtual X {}; // 4
class A : public Y, public Z {}; // 8

大小推導

  1. X:空類別插入 1 byte 佔位符。
  2. Y:虛繼承含指向虛基類指標 (4B) + 虛基類佔位 (1B) + 對齊填充 (3B) = 8B。VC6 最佳化:empty virtual base class 視為衍生類開頭一部分,省去 1B 及對齊,**實測 4B**。
  3. Z:同 Y,4B。
  4. A:共享單一 X 實體 (1B) + Y 非虛部分 (4B) + Z 非虛部分 (4B) = 9B → 對齊填充 3B = 12B。VC6 最佳化移除 X 佔位,**實測 8B**。

資料成員綁定規則

  • 成員函數參數名稱在首次遇見時決議。若嵌套 typedef 在參考**之後**出現,編譯器報錯。防禦風格:所有資料成員前置宣告。
  • Inline 函數本體在**整個類別宣告完成後**才分析求值。

資料成員佈局

  • 同一存取區段 (public/protected/private) 內順序 = 宣告順序。
  • 不同區段順序編譯器可自由調整 (實務上不調整)。
  • 編譯器合成成員 (如 vptr) 穿插其中。

資料成員存取

  • 靜態成員:唯一實體在全域資料段,存取轉為直接參考。取址得普通指標非成員指標。
  • 非靜態成員:obj.member 編譯期固定位移;ptr->member 若涉及虛基類成員,位移需執行期透過虛基類表/指標間接存取。

繼承對佈局影響

  1. 單一繼承無多態:衍生類 = 基類成員 + 自身成員。但分層宣告會導致對齊填充累積 (如 Concrete3 16B vs 扁平 8B),為保護基類子物件語意 (賦值不影響衍生成員)。
  2. 加上多態:引入 vptr、虛表、建構/解構開銷。
  3. 多重繼承:第一基類位移 0,第二基類需位移調整 (pv = (Vertex*)((char*)&v3d + sizeof(Point3d)))。
  4. 虛繼承:分為固定區 (直接存取) 與共享區 (虛基類,間接存取)。三大策略:
    • 每虛基類一指標
    • 虛基類表 (Microsoft)
    • 虛表負索引存放位移 (Sun/Foundation)

效率與指標

  • 單一/多重繼承非虛成員存取效率同非繼承。
  • 虛繼承間接存取效率差。
  • 成員指標值 = 實際位移 + 1 (區分空指標與第一成員)。多重繼承下第二基類成員指標需加基類大小調整。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved