进阶了解C++(2)——复杂的继承及其底层原理

       在上篇文章中,给出了关于继承这部分的相关知识,例如继承的定义,继承与默认成员函数等。本文将针对复杂的继承方式,

1. 复杂的继承方式:

1.1 单继承:

class Professor
{
public:int _age;string _name;
};class Teacher : public Professor
{public:int _tele;
};class Student : public Teacher
{
public:int _weight;
};

对于上面给出的代码,如果适用图形来表示这三个类之间的结构,具体如下:

对于这种一个子类只有一个直接父类时,称这种继承关系为单继承。

1.2 多继承: 

class Professor
{
public:int _age;string _name;
};class Teacher 
{public:int _tele;
};class Student : public Professor, public Teacher
{
public:int _weight;
};

对于上面给出代码,可以用下面的图形来表示这几个类的继承关系:

对于这种一个子类有两个或者两个以上的直接父类的关系,叫做多继承。

在多继承中,存在着一种特殊的继承关系:菱形继承,例如下面给出的代码:

class Person
{
public:int _ads;};class Professor : public Person
{
public:int _age;string _name;
};class Teacher : public Person
{public:int _tele;
};class Student : public Professor, public Teacher
{
public:int _weight;
};

其结构可由下图表示:

        对于菱形继承,其存在着一个问题,即数据冗余和二义性。这是因为在父类Person中,声明了成员变量_ads

        对于ProfessorTeacher这两个类中分别继承了Person。对于Student,分别继承了Professor,Teacher。因此,在Student中,存在着两个相同的成员变量_ads。对于这点,也可以在监视窗口进行查看:

由于存在着两个相同的成员变量,因此造成了数据冗余。至于二义性。则体现在对于这个成员变量进行访问时所体现,例如:

通过上面给出的图片可以看出,此时编译器并不知道,需要访问的变量_ads是从哪个父类继承而来的,因此造成了二义性。但是,可以通过显式访问的方法来解决二义性问题,即:

int main()
{Student s;s.Professor::_ads = 10;s.Teacher::_ads = 15;return 0;
}

不过,这种方式只能解决二义性问题,不能解决数据冗余问题。

为了解决数据冗余的问题,需要引入虚继承,具体操作如下:

class Person
{
public:int _ads;};class Professor : virtual public Person
{
protected:int _age;string _name;
};class Teacher1 : virtual public Person
{protected:int _tele;
};class Student : public Professor ,public Teacher
{
public:int _weight;
};

对于虚继承的使用原则,下面给出一个例子用于说明:

       假设上图给出的结构代表一个继承体系,根据上面对与数据冗余和二义性的介绍,上图中,在E中存在两个A类继承过来的内容从而造成数据冗余。在使用虚继承时,virtual造成数据冗余和二义性的源头上,例如图中,造成上述问题的源头是因为B,D分别继承了一次A。所以,在加入虚继承时,需要在B继承A以及D继承A时加上virtual

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/701164.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows安装HBuilderX

下载 HBuilderX下载地址: 下载地址 解压安装包 HBuilderX,Windows为zip包,解压后才能使用。 首先,选中下载的zip包,点击右键菜单,点击解压到当前文件夹进入解压后的文件夹,找到HBuilderX.exe&#xff0…

计算机组成原理(13)-----硬件多线程

目录 1.细粒度多线程 2.粗粒度多线程 3.同时多线程(SMT) 在不支持硬件多线程的处理器中,若要进行线程的切换,就需要保存和恢复线程的运行环境(否则会出现数据覆盖引起的错误)。 但在支持硬件多线程的处…

Android java中包的使用

一.包的使用 为了更好的实现项目中类的管理,提供包的概念。 package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。(若缺省该语句,则指定为无名包)。 它的格式为:package 顶层包名.子包名 ; 二.java中主要的包…

算法分析-面试1-字符串

文章目录 前言一、分类:看看就行了二、字符串API:创建和初始化:查询操作:比较操作:修改操作:截取操作:分割操作:格式化操作:连接操作(Java 8 及以后&#xff…

Delphi 11 安卓的蓝牙权限申请

上一篇博客里面的代码,演示如何申请安卓的权限。 如何申请安卓的蓝牙权限? 本博客之前有一篇文章写过。 现在 Google 要求 Android API Level 必须是 33。对于 BLE 的权限申请,有了一些新的要求。 以下描述,基于 Delphi 11。 …

vue页面基本增删改查

练手项目vue页面 新手前端轻喷: 效果如下 1、2两个部分组成: 对应代码中 element-ui中的 el-form 和 el-table 照着抄呗,硬着头皮来! 建议:认真读一遍你用的组件 那上边简单得列表举例: 建议大家手敲一个…

Unity与Android交互通信系列(5)

在前述文章中,已经使用了AndroidJavaProxy代理接口,本节我们将详细的介绍AndroidJavaProxy代理的用法。正如其名,AndroidJavaProxy是一个代理,它在Android端代码与Unity端代码交互中起一个桥接作用。其一般用法为在Java代码中定义…

【深度学习】主要提出者【Hinton】中国大会最新演讲【通往智能的两种道路】

「但我已经老了,我所希望的是像你们这样的年轻有为的研究人员,去想出我们如何能够拥有这些超级智能,使我们的生活变得更好,而不是被它们控制。」 6 月 10 日,在 2023 北京智源大会的闭幕式演讲中,在谈到如…

一键生成PDF即刻呈现:轻松创建无忧体验

在信息爆炸的时代,我们每天都在与各种文件、资料打交道。无论是工作中的报告、合同,还是学习中的笔记、论文,如何高效、安全地管理这些珍贵的资料,成为了我们迫切的需求。幸运的是,随着科技的发展,我们不再…

SpringBoot Admin 详解

SpringBoot Admin 详解 一、Actuator 详解1.Actuator原生端点1.1 监控检查端点:health1.2 应用信息端点:info1.3 http调用记录端点:httptrace1.4 堆栈信息端点:heapdump1.5 线程信息端点:threaddump1.6 获取全量Bean的…

【Python笔记-设计模式】享元模式

一、说明 享元模式是一种结构型设计模式,它摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。 (一) 解决问题 旨在减少大量相似对象创建时的内存开销 (二) 使用场景 大量…

AI:136-基于深度学习的图像生成与风格迁移

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

微服务三十五关

1.微服务有什么好处? 微服务优点很多,但是我们通常说一个东西好肯定会跟另一个东西比较, 通常说微服务好会和单体项目进行比较。以下是微服务相对于单体项目的一些显著好处: 首先,让我们讨论单体项目的一些主要缺点&a…

在线程调用的函数中使用pthread_exit同样会将线程退出

如上图所示,在func()函数中调用pthread_exit,同样可以退出当前线程; 类似的,如果func()函数中调用exit,可以直接退出整个进程。 return 是返回到函数调用处; pthread_exit是退出…

KTV点歌系统vue+springboot音乐歌曲播放器系统

目前现有的KTV点歌系统对于用户而言其在线点歌流程仍然过于繁琐,对于歌曲而言其系统安全性并不能保障。同时整套系统所使用的技术相对较为落后,界面不能动态化展示。相比较于其它同类型网站而言不能体现技术先进性。 1.2 项目目标 KTV点歌系统的后台开发…

wpf 3d 后台加载模型和调整参数

下载了一个代码,加载obj模型;它的参数在xaml里,模型加载出来刚好; 然后加载另一个obj模型;加载出来之后大,偏到很高和左的位置; 它之前的摄像机位置, Position"9.94759830064…

Apache celeborn 安装及使用教程

1.下载安装包 https://celeborn.apache.org/download/ 测0.4.0时出现https://github.com/apache/incubator-celeborn/issues/835 2.解压 tar -xzvf apache-celeborn-0.3.2-incubating-bin.tgz 3.修改配置文件 cp celeborn-env.sh.template celeborn-env.shcp log4j2.xml.…

前后端分离Vue+nodejs校园论坛bbs系统x450z

开发语言 node.js 框架:Express 前端:Vue.js 数据库:mysql 数据库工具:Navicat 开发软件:VScode本论文拟采用计算机技术设计并开发的论坛bbs系统,主要是为用户提供服务。使得用户可以在系统上查看帖子信息、签到积分等…

详解Megatron中的数据混合算法(BlendableDataset)

🧑‍💻 本文主要讲解Megatron早期版本中的数据混合算法。 目录 1. 数据混合2. 源码解析3. 证明部分&讨论4. 进一步优化 1. 数据混合 在谈源码之前,我们有必要先了解一下Megatron中的数据混合思想。 给定 n n n 个数据集 D 1 , D 2 , …

给定一个边与边可能相交的多边形,求它的轮廓线

大家好,我是前端西瓜哥。 最近遇到一个需求,给定一个多边形(边与边可能相交),求这个多边形的轮廓线。 需要注意的是,轮廓线多边形内不能有空洞,使用的不是常见的非零绕数规则(nonze…