C++虚函数表分析
作者:网络转载 发布时间:[ 2015/8/6 14:34:11 ] 推荐标签:.NET 测试开发技术
总结:
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
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南