C++虚函数表分析

发表于:2015-8-06 09:24

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:mfrbuaa    来源:51Testing软件测试网采编

  总结:
  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
32/3<123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号