从一个例子看内存布局

先看一个例子:(Win32 VS平台)

第一种情况:

class Base

{
public:
virtual void Func1() {};

};


class Derived: public Base
{
public:
virtual void Func2() {};
};


请问,sizeof(Derived)==?

相信这个很多人都可以知道答案4,这里Func1(),Func2()地址都放在Derived的虚函数表中。内存布局如下所示:

Derived 虚函数表指针   4         ----> | Base::Func1()  |  Derived::Func2() |



如果改成这样:

第二中情况:

class Base

{
public:
virtual void Func1() {};

};


class Derived: public virtual Base
{
public:
virtual void Func2() {};
};


只增加了个virtual关键字,sizeof(Derived)等于多少呢?

按照惯性思维,虚继承应该增加一个虚基类指针vbptr,大小在原来的基础上应增加4,为8。

但是在VS上调试却是12。这个就值得我们考虑下了。。。


通过修改编译选项在编译时即可查看内存布局,发现:

虚继承的时候,Func1()函数不在Derived的虚函数表中,而在其基类的虚函数表中。

这里涉及到虚继承的意义,是为了避免二义性。

假设将Func1()放入Derived的虚函数表中,按照此规则,再有一个类(Derived2)继承自Base,那么Func1()会放入Derived2的虚函数表中,

如果有一个类(Triple)继承自Derived和Derived2,那么Triple 的对象调用Func1()该如何调用呢?因为有2个Func1()

从这里我们可以推翻上面的假设。

这个时候编译器做了优化,给Base单独分配一个虚函数表指针。排列顺序是:

Derived 虚函数表指针  4         ----> | Derived::Func2() |

Derived 虚基类指针      4         

Base 虚函数表指针      4          ----> | Base::Func1() |




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值