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
Base2::dump1() 時,this 需調整 +12 (行 36)。this 指標調整是隱性成本,設計介面時宜傾向組合而非繼承。