虚基类
下面继续分析一下虚基类:
class w
{
private:
int m_w1;
int m_w2;
public:
w(){m_w1=m_w2=0;}
~w(){};
};
class clsB:virtual public w
{
private:
int m_b;
public:
clsB(){m_b=0;}
~clsB(){};
};
class clsC:virtual public w
{
private:
int m_c;
public:
clsC(){m_c=0;}
~clsC(){};
};
class clsA:public clsB,public clsC
{
private:
int m_a;
int m_b;
int m_c;
public:
clsA();
~clsA(){};
};
clsA::clsA():m_b(1),m_c(2),m_a(0)
{
}
void main()
{
clsA a; //局部实例类,main函数反汇编代码如下:
}

sub esp,24 在堆栈中为局部变量a分配clsA类大小字节(clsA有3*4=12字节成员变量, clsB有4字节成员变量+指向虚基类的指针4字节, clsC有4字节成员变量+指向虚基类的指针4字节, w有2*4=8字节成员变量.因此一共12+8+8+8=0x24)空间.
构造函数反汇编如下:

虚基类w的构造函数:

基类clsB的构造函数:

基类clsC的构造函数:

在堆栈中为变量a分配起始地址为: 0012FF5C,下图展示clsA类在栈的分配图:

可见前2个DWORD字节为基类clsB所占空间, clsB的第一个DWORD存放指向基类W的描述指针,看下指针指向数据结构:
该结构包含2个DWORD大小,第一个DWORD为0,第2个DWORD表示基类clsB的地址至虚基类w地址的偏移长度(0012FF5C+1C=0012FF78)
同理, 在上图的第3,4个DWORD位置为基类clsC所占空间, clsC的第一个DWORD存放指向基类W的描述指针,看下指针指向数据结构:
该结构包含2个DWORD大小,第一个DWORD为0,第2个DWORD表示基类clsC的地址至虚基类w地址的偏移长度(0012FF64+14=0012FF78)
因此,整个clsA类在栈的分配结构图如下:
