总结:
class CDerived2: virtual public CBase
{
public:
void fun(void) { }
virtual void vfun(void) { }
public:
int m_derived;
};
结果输出:
class CDerived2 size(20): +--- 0 | {vfptr} 4 | {vbptr} 8 | m_derived +--- +--- (virtual base CBase) 12 | {vfptr} 16 | m_valuable +--- CDerived2::$vftable@CDerived2@: | &CDerived2_meta | 0 0 | &CDerived2::vfun CDerived2::$vbtable@: 0 | -4 1 | 8 (CDerived2d(CDerived2+4)CBase) CDerived2::$vftable@CBase@: | -12 0 | &CDerived2::fun CDerived2::fun this adjustor: 12 CDerived2::vfun this adjustor: 0 vbi: class offset o.vbptr o.vbte fVtorDisp CBase 12 4 4 0 |
当中vftable@自身仅仅有一项:CDerived2::vfun(),vbtable@自身仅仅有一项:它virtual继承的父类CBase。而vftable@CBase原来的CBase::fun更新为CDerived2::fun。
CDerived3:virtual继承CBase,因此结构为vbtable@自身,member@自身。CBase结构
class CDerived3: virtual public CBase
{
public:
void fun(void) { }
public:
int m_derived3;
};
结果输出:
class CDerived3 size(16): +--- 0 | {vbptr} 4 | m_derived3 +--- +--- (virtual base CBase) 8 | {vfptr} 12 | m_valuable +--- CDerived3::$vbtable@: 0 | 0 1 | 8 (CDerived3d(CDerived3+0)CBase) CDerived3::$vftable@: | -8 0 | &CDerived3::fun CDerived3::fun this adjustor: 8 vbi: class offset o.vbptr o.vbte fVtorDisp CBase 8 0 4 0 CGDerived:继承CDerived2、CDerived3 class CGDerived: public CDerived2, public CDerived3 { public: void vfun() { } virtual void vgfun() { } public: int m_gd; }; |
输出:
class CGDerived size(32): +--- | +--- (base class CDerived2) 0 | | {vfptr} 4 | | {vbptr} 8 | | m_derived | +--- | +--- (base class CDerived3) 12 | | {vbptr} 16 | | m_derived3 | +--- 20 | m_gd +--- +--- (virtual base CBase) 24 | {vfptr} 28 | m_valuable +--- CGDerived::$vftable@CDerived2@: | &CGDerived_meta | 0 0 | &CGDerived::vfun 1 | &CGDerived::vgfun CGDerived::$vbtable@CDerived2@: 0 | -4 1 | 20 (CGDerivedd(CDerived2+4)CBase) CGDerived::$vbtable@CDerived3@: 0 | 0 1 | 12 (CGDerivedd(CDerived3+0)CBase) CGDerived::$vftable@CBase@: | -24 0 | &thunk: this-=12; goto CDerived2::fun CGDerived::vfun this adjustor: 0 CGDerived::vgfun this adjustor: 0 vbi: class offset o.vbptr o.vbte fVtorDisp CBase 24 4 4 0 |
因此首先是CDerived2的结构和CDerived3的结构,自己的新virtual方法vgfun则加入在最左父类CDerived2的虚函数表中。然后是自己的成员。
最后。CDerived2和CDerived3的父类CBase结构也带入当中。
它的fun默认指向CGDerived的最左父类CDerived2::fun。
CGG:继承CGDerived
class CGG: public CGDerived
{
public:
int m_kc;
};
输出:
class CGG size(36): +--- | +--- (base class CGDerived) | | +--- (base class CDerived2) 0 | | | {vfptr} 4 | | | {vbptr} 8 | | | m_derived | | +--- | | +--- (base class CDerived3) 12 | | | {vbptr} 16 | | | m_derived3 | | +--- 20 | | m_gd | +--- 24 | m_kc +--- +--- (virtual base CBase) 28 | {vfptr} 32 | m_valuable +--- CGG::$vftable@CDerived2@: | &CGG_meta | 0 0 | &CGDerived::vfun 1 | &CGDerived::vgfun CGG::$vbtable@CDerived2@: 0 | -4 1 | 24 (CGGd(CDerived2+4)CBase) CGG::$vbtable@CDerived3@: 0 | 0 1 | 16 (CGGd(CDerived3+0)CBase) CGG::$vftable@CBase@: | -28 0 | &thunk: this-=16; goto CDerived2::fun vbi: class offset o.vbptr o.vbte fVtorDisp CBase 28 4 4 0 |
添加一个变量,基本仅仅是把CGDerived的结构再套一层。最后加上自己的成员变量。
vbtable所指向的父类结构依旧在最后。
空类
class CBase2
{
};
输出:
class CBase2 size(1):
+---
+---
CD2:virtual继承则一定会创建vbtable,用vbptr指针指向,因此size为4
class CD2: virtual public CBase2
{
};
输出:
class CD2 size(4):
+---
0 | {vbptr}
+---
+--- (virtual base CBase2)
+---
CD2::$vbtable@:
0 | 0
1 | 4 (CD2d(CD2+0)CBase2)
vbi: class offset o.vbptr o.vbte fVtorDisp
CBase2 4 0 4 0
CE:非virtual继承CD2和CDerived2。于是依照类的声明顺序,先带入CDerived2的结构,再带入CD2的结构(而不是按继承顺序)
class CE: public CD2, public CDerived2
{
};
输出:
class CE size(24): +--- | +--- (base class CDerived2) 0 | | {vfptr} 4 | | {vbptr} 8 | | m_derived | +--- | +--- (base class CD2) 12 | | {vbptr} | +--- +--- +--- (virtual base CBase2) +--- +--- (virtual base CBase) 16 | {vfptr} 20 | m_valuable +--- CE::$vftable@CDerived2@: | &CE_meta | 0 0 | &CDerived2::vfun CE::$vbtable@CD2@: 0 | 0 1 | 4 (CEd(CD2+0)CBase2) 2 | 4 (CEd(CE+12)CBase) CE::$vbtable@CDerived2@: 0 | -4 1 | 12 (CEd(CDerived2+4)CBase) CE::$vftable@CBase@: | -16 0 | &thunk: this-=4; goto CDerived2::fun vbi: class offset o.vbptr o.vbte fVtorDisp CBase2 16 12 4 0 CBase 16 12 8 0 |