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

Visual C++ 8.0 物件記憶體佈局揭密:虛函數、多重繼承與虛擬繼承實測

     編輯:VC 教學

隱藏編譯器參數:一鍵輸出類別佈局

VC8 (VS 2005) 引入未文件化編譯選項 /d1reportSingleClassLayout<ClassName> 與 /d1reportAllClassLayout。設定位置:專案屬性 → C/C++ → 命令列 → 其他選項 加入 /d1reportSingleClassLayoutDerived,編譯後輸出視窗即顯示完整物件佈局。

測試案例:菱形虛擬繼承


class CommonBase { int co; };
class Base1 : virtual public CommonBase {
public: virtual void print1(){} virtual void print2(){}
private: int b1;
};
class Base2 : virtual public CommonBase {
public: virtual void dump1(){} virtual void dump2(){}
private: int b2;
};
class Derived : public Base1, public Base2 {
public: void print2(){} void dump2(){}
private: int d;
};

輸出佈局深度解讀

class Derived size(32):
+---
| +--- (base class Base1)
0 | | {vfptr}
4 | | {vbptr}
8 | | b1
| +---
| +--- (base class Base2)
12| | {vfptr}
16| | {vbptr}
20| | b2
| +---
24| d
+---
+--- (virtual base CommonBase)
28| co
+---

Derived::$vftable@Base1@:
0 | &Base1::print1
1 | &Derived::print2   // 覆寫

Derived::$vftable@Base2@:
0 | &Base2::dump1
1 | &Derived::dump2    // 覆寫

Derived::$vbtable@Base1@:
0 | -4                 // offset to vftable
1 | 24 (Derived d(Base1+4)CommonBase) // offset to virtual base

Derived::$vbtable@Base2@:
0 | -4
1 | 12 (Derived d(Base2+4)CommonBase)

Derived::print2 this adjustor: 0
Derived::dump2 this adjustor: 12

關鍵觀察點

  1. 物件總大小 32 位元組:Base1 (12) + Base2 (12) + Derived 成員 d (4) + 虛擬基類 CommonBase (4) = 32。
  2. 多重繼承產生多個 this 指標:Base1 子物件起始 0,Base2 起始 12。呼叫 Base2::dump1() 時,this 需調整 +12 (行 36)。
  3. 虛函數表各自獨立:Base1、Base2 各有一個 vfptr,Derived 覆寫函數出現在對應虛表槽位。
  4. 虛基類表 (vbtable) 解決共享問題:Base1、Base2 各持 vbptr 指向各自 vbtable,記錄虛基類 CommonBase 相對 vbptr 的位移。Base2 vbptr 在 Derived 位移 16,vbtable 記錄 +12 → CommonBase 絕對位移 28。
  5. 虛基類置於最尾端:遵循 VC 佈局慣例,虛基類子物件排在最派生類自身成員之後。

實務啟示

  • 多重繼承下 this 指標調整是隱性成本,設計介面時宜傾向組合而非繼承。
  • 虛擬繼承雖解決菱形問題,但引入 vbptr/vbtable 額外間接存取與記憶體開銷。
  • 此編譯器輸出功能極利於除錯物件切割、指標轉型錯誤、效能分析,比閱讀《Inside C++ Object Model》更直觀即時。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved