C++虚继承下的内存模型(二)
对于虚继承,恰恰和普通继承相反,大部分编译器会把基类成员变量放在派生类成员变量的后面,这样随着继承层级的增加,基类成员变量的偏移就会改变,就得通过其他方案来计算偏移量。
下面我们来一步一步地分析虚继承时的对象内存模型。
- 修改上面的代码,使得 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 的内存模型就会发生变化,如下图所示:
不管是虚基类的直接派生类还是间接派生类,虚基类的子对象始终位于派生类对象的最后面。
- 再假设 A 是 B 的虚基类,B 又是 C 的虚基类,那么各个对象的内存模型如下图所示:
从上面的两张图中可以发现,虚继承时的派生类对象被分成了两部分:
- 不带阴影的一部分偏移量固定,不会随着继承层次的增加而改变,称为固定部分;
- 带有阴影的一部分是虚基类的子对象,偏移量会随着继承层次的增加而改变,称为共享部分。
当要访问对象的成员变量时,需要知道对象的首地址和变量的偏移,对象的首地址很好获得,关键是变量的偏移。对于固定部分,偏移是不变的,很好计算;而对于共享部分,偏移会随着继承层次的增加而改变,这就需要设计一种方案,在偏移不断变化的过程中准确地计算偏移。各个编译器正是在设计这一方案时出现了分歧,不同的编译器设计了不同的方案来计算共享部分的偏移。
对于虚继承,将派生类分为固定部分和共享部分,并把共享部分放在最后,几乎所有的编译器都在这一点上达成了共识。主要的分歧就是如何计算共享部分的偏移,可谓是百花齐放,没有统一标准。
C++虚继承下的内存模型(二)相关推荐
- C++虚继承下的内存模型(一)
简单的面向对象,只有单继承或多继承的情况下,内存模型很好理解,编译器实现起来也容易,C++ 的效率和 C 的效率不相上下.一旦和 virtual 关键字扯上关系,使用到虚继承或虚函数,内存模型就变得混 ...
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7883531 一.虚函数的工作原理 虚函数的实现要求对象携带额 ...
- C++20 Atomic 原子 内存模型(二)
C++20 Atomic 原子 内存模型(二) 原子是C++内存模型的基础 强/弱内存模型 1. 强内存模型 Leslie Lamport 定义了顺序一致性的概念 顺序一致性提供两个保证: 指令按源码 ...
- Java内存模型(二)
volatile型变量的特殊规则 volatile是Java虚拟机提供的最轻量级的同步机制,当一个变量被定义成volatile后,它将具备两种特性,第一是保证此变量对所有线程的可见性,这里的" ...
- 一文读懂C++虚继承的内存模型
一文读懂C++虚继承的内存模型 1.前言 2.多继承存在的问题 3.虚继承简介 4.虚继承在标准库中的使用 5.虚继承下派生类的内存布局解析 6.总结 1.前言 C++虚继承的内存模型是一个经典的问题 ...
- 内存首地址为1000h_C++虚继承,菱形继承,内存分布
前言 在叙述C++虚继承之前,我先给大家抛出一个问题.例如现在有4个类,分别是class A, class B, class C, class D.它们的关系如下图. 如上如所示,class B和cl ...
- 【C++拾遗】 从内存布局看C++虚继承的实现原理
2019独角兽企业重金招聘Python工程师标准>>> 原创作品,转载请标明:http://blog.csdn.net/xiejingfa/article/details/48028 ...
- C++中虚函数继承类的内存占用大小计算
前半部分转自https://www.cnblogs.com/SeekHit/p/7570247.html 其中为32位字节对齐,后半部分给出自己的理解. 字节对齐的原理见链接https://www.c ...
- c++对象模型05:虚继承内存布局
虚继承 虚继承解决了菱形继承中最派生类拥有多个间接父类实例的情况.虚继承的派生类的内存布局与普通继承很多不同,主要体现在: 虚继承的派生类,如果定义了新的虚函数,则编译器为其生成一个虚函数指针(vpt ...
最新文章
- ArcEngine数据删除几种方法和性能比较
- php扩展 静态库,编译PHP扩展的方法
- 1143 Lowest Common Ancestor 甲级
- manifest.mf._MANIFEST.MF和feature.xml版本控制规则
- springcloud使用zipkin和rabbitmq进行服务链路追踪
- 最大后验估计与共轭分布
- java各个版本下载地址
- 编程珠玑第三章笔记加习题解答
- 数据库管理员、系统分析员、数据库设计人员,应用程序员的职责是什么?
- 王道数据结构3.2.5——1、循环队列中设置tag区分头指针front和队尾指针rear相等时队列的状态是空还是满
- 产品基础学习笔记---传智教育
- 阿里云服务器绑定域名、esc绑定域名、域名备案
- 云计算基础2-什么是云存储?
- 常用的c语言,C语言常用.docx
- 研招网官方:关于考研报名的提醒!
- 51nod 1737 配对 【树形dp】
- 一文带你享受数学之优美
- html 一键复制 ios,兼容安卓和ios实现一键复制内容到剪切板
- 华云大咖说 | 安超信创桌面云金融行业解决方案
- 王思聪花100万组装电脑!跑分97000,亚洲排名第一,全世界第四。