前言
在之前文章中,写过继承的基本语法: 文章:【从基本语法到菱形继承】
但对菱形继承的构造过程和内存布局还没有细说,本文来对这些概念进行讲解。
菱形继承
示例代码
class Base
{
private:
int value;
public:
Base(int x = 0) : value(x) {}
};
class Object_1 : virtual public Base
{
private:
int num;
public:
Object_1(int x = 0) : Base(x + 10), num(x) {}
};
class Object_2 : virtual public Base
{
private:
int sum;
public:
Object_2(int x = 0) : Base(x + 10), sum(x) {}
};
class Test : public Object_1, public Object_2
{
private:
int total;
public:
Test(int x = 0)
: total(x), Object_1(x + 10), Object_2(x + 20), Base(x + 100)
{
}
};
继承图示
构造过程
内存布局
内存模型
内存布局: 输入t1的地址,得到:
对于Base的基类,Object_1和Obejct_2如何找到它的? 其实两个派生类里面并不是指针,而是记录了一个偏移量,因为在构造过程中,这一块内存就在一起,不需要拿指针指向某个位置,又不是分散在内存其他地方,书上所说的vbptr是个指针,是为了更好理解。
图示: 在Object_1中,有一个偏移量 0x14,就是十进制的20,意味着如果要找到Base基类,需要偏移20字节。
同理:Object_2里面存放了一个偏移量 0x 0c,即十进制的12,要找到基类Base,需要偏移12个字节。
最终的图示可以这样理解
end
|