C++对象模型之虚基类表和虚函数表的布局(三)
注:本文的c++对象结构模型基于vs编译器的win32环境.
链接: C++对象模型之虚基类表和虚函数表的布局(一).
链接: C++对象模型之虚基类表和虚函数表的布局(二).
三、虚基类和虚函数
在前两篇文章中。我们分析了虚函数和虚基类相关的知识,现在我们把他们结合起来观察。
class Grand
{
public:
int m_grand = 1;
virtual void g() { cout << "Grand::g()" << endl; }
};
class Base1 : virtual public Grand
{
public:
int m_base1 = 2;
static int n_base1;
virtual void g() { cout << "Base1::g()" << endl; }
virtual void x() { cout << "Base1::x()" << endl; }
virtual void y() { cout << "Base1::y()" << endl; }
virtual void z() { cout << "Base1::z()" << endl; }
};
int Base1::n_base1 = 10; //静态成员变量在类外初始化
class Base2 : virtual public Grand
{
public:
int m_base2 = 3;
virtual void g() { cout << "Base2::g()" << endl; }
virtual void a() { cout << "Base2::a()" << endl; }
virtual void b() { cout << "Base2::b()" << endl; }
};
class Derived : public Base1, public Base2
{
public:
int m_derived = 4;
virtual void g() { cout << "Derived::g()" << endl; }
virtual void y() { cout << "Derived::y()" << endl; }
virtual void m() { cout << "Derived::m()" << endl; }
virtual void n() { cout << "Derived::n()" << endl; }
};
测试代码:
(1)首先看看这几个类对象占内存的大小
int main()
{
cout << sizeof(Grand) << endl; //8byte
cout << sizeof(Base1) << endl; //20byte
cout << sizeof(Base2) << endl; //20byte
cout << sizeof(Derived) << endl; //36byte
return 0;
}
根据前文中的分析我们很容易得出对象的空间内包含了哪些东西:非静态成员变量、虚函数指针、虚基类指针。以Derived为例(36字节),包含4个数据成员16字节、三个虚函数指针(来自Grand、Base1、Base2)共12字节、两个虚基类指针(来自Base、Base2)共8字节。
(2)其次看看类对象的空间分布

这里直接上结果,就不放上代码了。
(3)再看看虚基类表和虚函数表的布局

四、后记
至此就完成了对虚基类表和虚函数表的布局的分析,当然,对于不同的编译器,处理虚函数以及虚基类的手法各不相同,重要的是掌握这样一种探究底层的方法还有获得刨根问底的精神,知其然而知其所以然。
本文深入解析C++中虚基类和虚函数的内存布局,通过具体示例,展示了不同类对象的内存占用及虚基类表、虚函数表的详细布局。适用于C++进阶学习。
2855

被折叠的 条评论
为什么被折叠?



