当前位置:网站首页>虚继承的原理
虚继承的原理
2022-07-31 23:34:00 【华为云】
虚继承的原理
C++编译器是如何通过虚继承解决数据冗余和二义性的呢?
1.通过监视窗口已经看不到真实的存在,因为监视窗口被编译器处理过
2.建议使用内存窗口来进行查看
虽然虚继承补了菱形继承的坑,但是也付出了很大的代价, 1.对象模型更复杂了,学习理解成本很高 2.有一定的效率影响
虚拟继承解决数据冗余和二义性的原理 为了研究虚拟继承原理,我们给出了一个简化的菱形继承继承体系,再借助内存窗口观察对象成员的模型。
未使用虚继承:
class A{public: int _a;};class B : public A{public: int _b;};class C : public A{public: int _c;};class D : public B, public C{public: int _d;};int main(){ D d; d.B::_a = 1; d.C::_a = 2; d._b = 3; d._c = 4; d._d = 5; return 0;}
未使用虚继承
下图是菱形继承的内存对象成员模型:这里可以看到数据冗余
先继承B,再继承C 我们也可也看出, 先继承的在前面,后继承的在后面,
这里就可以看出为什么菱形继承导致了数据冗余和二义性,根本原因就是D类对象当中含有两个_a成员。
使用虚拟继承后
class A{public: int _a;};class B : virtual public A{public: int _b;};class C : virtual public A{public: int _c;};class D : public B, public C{public: int _d;};int main(){ D d; d.B::_a = 1; d.C::_a = 2; d._b = 3; d._c = 4; d._d = 5; return 0;}
其中D类对象当中的_a成员被放到了最后,而在原来存放两个_a成员的位置变成了两个指针,这两个指针叫虚基表指针,它们分别指向一个虚基表。 虚基表中包含两个数据,第一个数据是为多态的虚表预留的存偏移量的位置(这里我们不必关心),第二个数据就是当前类对象位置距离公共虚基类的偏移量。 也就是说,这两个指针经过一系列的计算,最终都可以找到成员_a
注意:虚基表中存的是相对地址
下图是菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下面,这个A 同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指向的一张表。这两个指 针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A。
下面是上面的Person关系菱形虚拟继承的原理解释:
若是将D类对象赋值给B类对象,在这个切片过程中,就需要通过虚基表中的第二个数据找到公共虚基类A的成员,得到切片后该B类对象在内存中仍然保持这种分布情况
子给父 -> 切片
int main(){ D d; d.B::_a = 1; d.C::_a = 2; d._b = 3; d._c = 4; d._d = 5; B b = d;//切片行为 return 0;}
_a对象仍然存储在该B类对象的最后
只要有公共的祖先类就是菱形继承
例如:
边栏推荐
- [1161. The maximum sum of elements in the layer]
- SQL injection Less47 (error injection) and Less49 (time blind injection)
- (26)Blender源码分析之顶层菜单的关于菜单
- Flutter教程之 01配置环境并运行demo程序 (教程含源码)
- cobaltstrike
- Interview Blitz 69: Is TCP Reliable?Why?
- What is customer profile management?
- /etc/sysconfig/network-scripts configure the network card
- 【MATLAB项目实战】LDPC-BP信道编码
- When can I use PushGateway
猜你喜欢
I don't know what to do with sync issues
一行代码解决CoreData托管对象属性变更在SwiftUI中无动画效果的问题
Interview assault 69: TCP reliable?Why is that?
Design of Fire and Anti-theft System Based on Single Chip GSM
什么是客户画像管理?
SQL27 View user details of different age groups
Pytest初体验
Document management and tools in the development process
Dry goods | 10 tips for MySQL add, delete, change query performance optimization
Unity-通过预制件和克隆方法动态实现各个UGUI下控件的创建和显示
随机推荐
一文概述:VPN的基本模型及业务类型
逐步手撕轮播图3(保姆级教程)
无状态与有状态的区别
NIO编程
How to reduce the gap between software design and implementation
How to import a Golang external package and use it?
推荐系统:常用评价指标总结【准确率、精确率、召回率、命中率、(归一化折损累计增益)NDCG、平均倒数排名(MRR)、ROC曲线、AUC(ROC曲线下的面积)、P-R曲线、A/B测试】
How to Design High Availability and High Performance Middleware - Homework
Shell common script: Nexus batch upload local warehouse script
了解下C# 匿名方法
Pytest first experience
基于RT1052 Aworks nanopb string 类型固定长度使用方式(二十七)
date命令
如何导入 Golang 外部包并使用它?
助力数字政府建设,中科三方构建域名安全保障体系
[QNX Hypervisor 2.2用户手册]9.15 suppress
硬件设备计算存储及数据交互杂谈
嵌入式开发没有激情了,正常吗?
SQL注入 Less54(限制次数的SQL注入+union注入)
To help the construction of digital government, the three parties of China Science and Technology build a domain name security system