C++ 对象内存布局

单一的一般继承

 

可见以下几个方面:

1. 虚函数表在最前面的位置

2. 成员变量根据其继承和声明的顺序一次放在后面

3. 在单一继承中, 被 overwrite 的虚函数在虚函数表中得到更新

 

多重继承

 

我们可以看到

1. 每个父类都有自己的虚函数表

2. 子类的成员函数被放在第一个父类的表中

3. 内存布局中, 父类按照声明顺序一次排列

4. 每个父类的虚表中的 f() 函数都被 overwrite 成了子类的 f(). 这样做就是为了解决不同父类类型的指针指向同一个子类实例.

 

重复继承

我们可以看到, 最顶端的父类 B 其成员变量存在于 B1 和 B2 中, 并被 B 给继承下来了. 而在 D 中, 其有 B1 和 B2 的实例, 于是 B 的成员在 D 的实例中存在两份, 一份是 B1 继承来的, 另一个份是 B1 继承来的. 所以, 我们使用如下语句, 则会产生二义性编译错误

D d;

d.ib = 0; // 二义性错误

d.B1::ib = 1; // ok

d.B2::ib = 2; // ok

 

钻石型虚拟多重继承

 

 

结论

1. 一个 virtual base class 只会在 Derived class 中存在一份实体, 无论该基类被继承多少次

2. (1) 的具体实现是将 D 对象分割成两部分, 分别是不变局部和共享局部. 不变局部部分, 无论后继如何演化, 总有固定的偏移量, 所以这部分数据可以直接存取. 至于共享局部, 表现出来的就是虚拟继承的基类子对象, 这一部分数据的位置随着派生操作而变化, 因此是间接存取.

3. 一般的策略是存放不变局部, 然后在每一个派生对象中插入指针 vbptr, 每一个指针指向基类子对象

4. 上图中, 第一个 vbptr 的值是 -4 和 40, 第二个是  -4 和 24. 40, 24 分别是 B1, B2 到基类子对象的偏移. -4 是 vbptr 到 _vfptr 的偏移.

 

转自: http://www.cnblogs.com/liu-jun/archive/2013/05/17/3083736.html

http://blog.csdn.net/haoel/article/details/3081328

转载于:https://www.cnblogs.com/zhouzhuo/p/3640749.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值