对于虚继承,恰恰和普通继承相反,大部分编译器会把基类成员变量放在派生类成员变量的后面,这样随着继承层级的增加,基类成员变量的偏移就会改变,就得通过其他方案来计算偏移量。

下面我们来一步一步地分析虚继承时的对象内存模型。

  1. 修改上面的代码,使得 A 是 B 的虚基类:
#include <iostream>
using namespace std;class A{protected:int m_a1;int m_a2;
};
class B: virtual public A{protected:int b1;int b2;
};
class C: public B{protected:int c1;int c2;
};
class D: public C{protected:int d1;int d2;
};
int main(){A obj_a;B obj_b;C obj_c;D obj_d;return 0;
}

此时 obj_b、obj_c、obj_d 的内存模型就会发生变化,如下图所示:


不管是虚基类的直接派生类还是间接派生类,虚基类的子对象始终位于派生类对象的最后面。

  1. 再假设 A 是 B 的虚基类,B 又是 C 的虚基类,那么各个对象的内存模型如下图所示:


从上面的两张图中可以发现,虚继承时的派生类对象被分成了两部分:

  • 不带阴影的一部分偏移量固定,不会随着继承层次的增加而改变,称为固定部分;
  • 带有阴影的一部分是虚基类的子对象,偏移量会随着继承层次的增加而改变,称为共享部分。

当要访问对象的成员变量时,需要知道对象的首地址和变量的偏移,对象的首地址很好获得,关键是变量的偏移。对于固定部分,偏移是不变的,很好计算;而对于共享部分,偏移会随着继承层次的增加而改变,这就需要设计一种方案,在偏移不断变化的过程中准确地计算偏移。各个编译器正是在设计这一方案时出现了分歧,不同的编译器设计了不同的方案来计算共享部分的偏移。

对于虚继承,将派生类分为固定部分和共享部分,并把共享部分放在最后,几乎所有的编译器都在这一点上达成了共识。主要的分歧就是如何计算共享部分的偏移,可谓是百花齐放,没有统一标准。

C++虚继承下的内存模型(二)相关推荐

  1. C++虚继承下的内存模型(一)

    简单的面向对象,只有单继承或多继承的情况下,内存模型很好理解,编译器实现起来也容易,C++ 的效率和 C 的效率不相上下.一旦和 virtual 关键字扯上关系,使用到虚继承或虚函数,内存模型就变得混 ...

  2. C++中虚函数工作原理和(虚)继承类的内存占用大小计算

    转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7883531 一.虚函数的工作原理       虚函数的实现要求对象携带额 ...

  3. C++20 Atomic 原子 内存模型(二)

    C++20 Atomic 原子 内存模型(二) 原子是C++内存模型的基础 强/弱内存模型 1. 强内存模型 Leslie Lamport 定义了顺序一致性的概念 顺序一致性提供两个保证: 指令按源码 ...

  4. Java内存模型(二)

    volatile型变量的特殊规则 volatile是Java虚拟机提供的最轻量级的同步机制,当一个变量被定义成volatile后,它将具备两种特性,第一是保证此变量对所有线程的可见性,这里的" ...

  5. 一文读懂C++虚继承的内存模型

    一文读懂C++虚继承的内存模型 1.前言 2.多继承存在的问题 3.虚继承简介 4.虚继承在标准库中的使用 5.虚继承下派生类的内存布局解析 6.总结 1.前言 C++虚继承的内存模型是一个经典的问题 ...

  6. 内存首地址为1000h_C++虚继承,菱形继承,内存分布

    前言 在叙述C++虚继承之前,我先给大家抛出一个问题.例如现在有4个类,分别是class A, class B, class C, class D.它们的关系如下图. 如上如所示,class B和cl ...

  7. 【C++拾遗】 从内存布局看C++虚继承的实现原理

    2019独角兽企业重金招聘Python工程师标准>>> 原创作品,转载请标明:http://blog.csdn.net/xiejingfa/article/details/48028 ...

  8. C++中虚函数继承类的内存占用大小计算

    前半部分转自https://www.cnblogs.com/SeekHit/p/7570247.html 其中为32位字节对齐,后半部分给出自己的理解. 字节对齐的原理见链接https://www.c ...

  9. c++对象模型05:虚继承内存布局

    虚继承 虚继承解决了菱形继承中最派生类拥有多个间接父类实例的情况.虚继承的派生类的内存布局与普通继承很多不同,主要体现在: 虚继承的派生类,如果定义了新的虚函数,则编译器为其生成一个虚函数指针(vpt ...

最新文章

  1. ArcEngine数据删除几种方法和性能比较
  2. php扩展 静态库,编译PHP扩展的方法
  3. 1143 Lowest Common Ancestor 甲级
  4. manifest.mf._MANIFEST.MF和feature.xml版本控制规则
  5. springcloud使用zipkin和rabbitmq进行服务链路追踪
  6. 最大后验估计与共轭分布
  7. java各个版本下载地址
  8. 编程珠玑第三章笔记加习题解答
  9. 数据库管理员、系统分析员、数据库设计人员,应用程序员的职责是什么?
  10. 王道数据结构3.2.5——1、循环队列中设置tag区分头指针front和队尾指针rear相等时队列的状态是空还是满
  11. 产品基础学习笔记---传智教育
  12. 阿里云服务器绑定域名、esc绑定域名、域名备案
  13. 云计算基础2-什么是云存储?
  14. 常用的c语言,C语言常用.docx
  15. 研招网官方:关于考研报名的提醒!
  16. 51nod 1737 配对 【树形dp】
  17. 一文带你享受数学之优美
  18. html 一键复制 ios,兼容安卓和ios实现一键复制内容到剪切板
  19. 华云大咖说 | 安超信创桌面云金融行业解决方案
  20. 王思聪花100万组装电脑!跑分97000,亚洲排名第一,全世界第四。

热门文章

  1. C1之路 | 训练任务01-进制与信息编码
  2. thrift多平台安装
  3. s:textfield format date
  4. uva 10034 Freckles (kruskal||prim)
  5. Oracle的悲观锁和乐观锁
  6. 利用Gearman,搭建异步分布式计算平台
  7. [SD2.0大会]王坚:Data–centric Computing
  8. 网络游戏,原罪和救赎
  9. Linux、Windows进程间通信
  10. php 模板使用,TMDPHP 模板引擎使用教程