前言

菱形继承是多重继承中跑不掉的,Java拿掉了多重继承,辅之以接口。C++中虽然没有明确说明接口这种东西,但是只有纯虚函数的类可以看作Java中的接口。在多重继承中建议使用“接口”,来避免多重继承中可能出现的各种问题。本文将给大家详细介绍关于C++菱形继承和虚继承的相关内容,分享出来供大家参考学习,话不多说了,来一起看看详细的介绍吧。
继承:
1. 单继承–一个子类只有一个直接父类时称这个继承关系为单继承
2. 多继承–一个子类有两个或以上直接父类时称这个继承关系为多继承
例如下面这两个例子:
例一(单继承):
class A
{
public:
int _a;
};
class B : public A // B是 子类/派生类, 公有 继承父类/基类 A
{
public:
int _b;
};
class C : public B //C是 子类/派生类, 公有继承 父类/基类 B
{
public:
int _c;
};
例二(多继承):
class A
{
public:
int _a;
};
class B
{
public:
int _b;
};
class C : public A , public B // 子类C同时公有继承父类A和父类B
{
public:
int _c;
};
用图很形象的表示一下:
但是在使用过程中,很容易出现一种继承关系叫菱形继承。就好比下面这种继承方式。
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;
};
继承的方式简单画出来就是下面这样:
我们在使用过程中会发现以下缺点:
1、 当我们用D类创建出对象d时,可以访问到_a,但是一旦编译就会出现错误。错误说明为: C2385: 对“_a”的访问不明确。从图中也可以看出,如果用d访问_a时,可能在B类里,也同时可能存在于c类中。这就是所谓的“二义性”;
2、虽然B类和C类都公有继承A,但是在D类公有继承B,C时,存放了两份A类,造成了数据的冗余。
C++针对这种缺陷提出了另外一种继承方式叫做虚继承。
虚继承
C++使用虚拟继承(Virtual Inheritance),解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。
◇语法:
class 派生类: virtual 基类1,virtual 基类2,…,virtual 基类n
{
…//派生类成员声明
};
在有了虚继承的概念后,我们就可以规避上面的缺点了。
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;
};
当我们使用了虚继承时,继承模型就改变为下面这样:
由于我所使用的是vs2015,在此编译器下对应的处理方式就是这样。将class B 和 class C设置为虚继承后,编译器将class A存放在了最下端,并在B和C类的前四个字节中存放了一个地址,当我们访问过去向下再多看四个字节时就会发现这其中存放了一个数字。而这个数字就类似于“偏移量”,记录了该类的首地址距父类首地址之间的字节差距。比如class B中,我们找到对应数字为14,但是这个数字是16进制,转为10进制为20,在class B的首地址加上20个字节就恰好是class A的首地址,同理class C。
因此在class D访问_a时,就不会产生二义性,_a数据也只存放了一份,解决了之前菱形继承所带来的问题。
但是还存在一个问题:当我们求没有使用虚继承之前的class D的大小,结果是20,但是在使用了虚继承后大小变为24。所以虽然使用虚继承解决数据冗余问题也带来了性能上的损耗。(关于如何计算内存大小,可以参考此链接。)
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# c
# 菱形继承
# 多继承
# 菱形
# 虚继承
# C++菱形继承和虚继承的实现
# 子类
# 当我们
# 只有一个
# 派生类
# 但是在
# 设置为
# 的是
# 时称
# 就会
# 使用了
# 放在
# 相关内容
# 在此
# 说了
# 不多
# 中有
# 并在
# 提出了
# 很容易
# 能在
相关文章:
如何在Tomcat中配置并部署网站项目?
家庭服务器如何搭建个人网站?
实惠建站价格推荐:2025年高性价比自助建站套餐解析
如何选择PHP开源工具快速搭建网站?
制作企业网站建设方案,怎样建设一个公司网站?
用v-html解决Vue.js渲染中html标签不被解析的问题
昆明网站制作哪家好,昆明公租房申请网上登录入口?
如何在西部数码注册域名并快速搭建网站?
简历在线制作网站免费版,如何创建个人简历?
高防服务器如何保障网站安全无虞?
高防服务器:AI智能防御DDoS攻击与数据安全保障
网站图片在线制作软件,怎么在图片上做链接?
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
如何快速生成高效建站系统源代码?
家具网站制作软件,家具厂怎么跑业务?
建站主机空间推荐 高性价比配置与快速部署方案解析
如何在IIS中配置站点IP、端口及主机头?
建站之星伪静态规则如何正确配置?
广州商城建站系统开发成本与周期如何控制?
深圳网站制作培训,深圳哪些招聘网站比较好?
佛山网站制作系统,佛山企业变更地址网上办理步骤?
非常酷的网站设计制作软件,酷培ai教育官方网站?
网站制作企业,网站的banner和导航栏是指什么?
青浦网站制作公司有哪些,苹果官网发货地是哪里?
建站之星各版本价格是多少?
盘锦网站制作公司,盘锦大洼有多少5G网站?
活动邀请函制作网站有哪些,活动邀请函文案?
建站之星如何快速解决建站难题?
制作宣传网站的软件,小红书可以宣传网站吗?
建站之星如何实现五合一智能建站与营销推广?
浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?
XML的“混合内容”是什么 怎么用DTD或XSD定义
如何选择建站程序?包含哪些必备功能与类型?
北京网站制作网页,网站升级改版需要多久?
建站三合一如何选?哪家性价比更高?
如何设置并定期更换建站之星安全管理员密码?
黑客如何利用漏洞与弱口令入侵网站服务器?
,网站推广常用方法?
营销式网站制作方案,销售哪个网站招聘效果最好?
广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?
简单实现Android验证码
如何通过VPS建站实现广告与增值服务盈利?
如何获取上海专业网站定制建站电话?
如何快速搭建高效香港服务器网站?
如何快速上传自定义模板至建站之星?
建站之星后台管理如何实现高效配置?
如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法
建站之星安装提示数据库无法连接如何解决?
制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?
*请认真填写需求信息,我们会在24小时内与您取得联系。