一、结论
虚基类表的作用是帮助编译器找到该类中的虚基类中各个成员变量在内存布局中的位置。 虚基类表中的值是偏移值,即:各个虚基类的成员变量在子类中的内存布局中相对于虚函数指针的偏移值。
二、栗子
1、唯一父类是虚基类
(1)源码
class Grand
{
public:
int i_grand_;
};
class Parent : public virtual Grand
{
public:
int i_parent_;
};
int main()
{
Parent Pobj;
Pobj.i_grand_ = 1;
Pobj.i_parent_ = 2;
return 0;
}
(2)分析
上述代码转换成汇编,如下所示:
根据汇编代码可知,编译器正是通过虚基类表找到了虚基类的成员变量 i_grand_ 的位置。Pobj、vbptr 和 vbtable 的关系如下图所示:
2、父类有虚基类和普通父类
(1)源码
#include <iostream>
class Grand1
{
public:
int i_grand1_;
};
class Grand2
{
public:
int i_grand2_;
};
class Grand3
{
public:
int i_grand3_;
};
class Grand4
{
public:
int i_grand4_;
};
class Grand5
{
public:
int i_grand5_;
};
class Parent : public virtual Grand1,
public Grand2,
virtual public Grand3,
virtual public Grand4,
virtual public Grand5
{
public:
int i_parent_;
};
int main()
{
std::cout << sizeof(Parent) << std::endl;
Parent Pobj;
Pobj.i_grand1_ = 1;
Pobj.i_grand2_ = 2;
Pobj.i_grand3_ = 3;
Pobj.i_grand4_ = 4;
Pobj.i_grand5_ = 5;
Pobj.i_parent_ = 6;
return 0;
}
(2)分析
上述代码转成汇编,如下所示:
根据汇编代码可知,编译器正是通过虚基类表找到了虚基类的成员变量 i_grand1_、i_grand3_、i_grand4_、i_grand5_, 的位置。Pobj、vbptr 和 vbtable 的关系如下图所示:
(SAW:Game Over!)