【C++】继承(下) 单继承 | 多继承 | 菱形继承 | 继承和组合

一、单/多/菱形继承

1.单继承

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

2.多继承

一个子类有两个或以上直接父类时称这个继承关系为多继承。

举个实例:新老师进学校工作时,一般会作为助教老师,一边代课教书,一边跟着经验足的老教师后头 学习一阵子。这时我们定义出的"Assistant"类,就同时具有老师、学生这两种属性。这就是多继承的思想。

多继承的书写格式为:逗号+继承方式+父类名

3.菱形继承

是多继承的一种特殊情况。

a.产生的问题

这种继承结构会导致二义性 以及空间浪费等问题。

什么叫产生二义性?我用上面的例子解释给你听:

class Person
{
public:Person(string str=""):_name(str){}string _name="";
};
​
class Student : public Person  //继承了person
{
public:Student():Person("student"){}int _num=0;
};
​
class Teacher : public Person   //继承了person
{
public:Teacher():Person("teacher"){}int _id=0;
};class Assistant :public Student, public Teacher   //继承的这俩,都是person的派生类
{};
int main() {Assistant a;cout << a._name << endl;return 0;
}

这样写,编译是无法通过的:

这是因为此时的a里面,有两个_name,编译器不知道用哪个了:

如果还是不理解,可以看这张图:

这就产生了二义性。并且,由于Assistant中有两份 _name的拷贝,当 _name要用的空间很大的话,就会造成空间浪费。

b.如何解决

那遇到菱形继承的情况,要怎么解决二义性和数据冗余的问题呢?

Way1. 显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决。

cout << a.Student::_name << endl;
cout << a.Teacher::_name << endl;

Way2. 虚拟继承

先来介绍下虚拟继承:虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。其中,这个被共享的基类就称为虚基类。

怎么设为虚继承呢?在继承方式前加上virtual关键字即可。

(注意:虚拟继承是专门用于处理 菱形继承 的手段,不要在其他地方去使用)

class Person
{
public:Person(string str=""):_name(str){}string _name="";
};
​
class Student :virtual public Person   //虚继承
{
public:Student():Person("student"){}int _num=0;
};
​
class Teacher :virtual public Person   //这俩都设为虚继承
{
public:Teacher():Person("teacher"){}int _id=0;
};
​
class Assistant :public Student, public Teacher
{};
int main() {Assistant a;cout << a._name << endl;return 0;
}

这里编译器做了优化处理,看似有3个Person,实际上只有一个,这仨都是同一个:

虚继承使得从不同路径继承来的同名基类,在派生类中只产生一个实例,避免了二义性问题。

4.劝告

一般不建议设计出多继承,并且,如果不是迫不得已,不要设计出菱形继承!否则在复杂度及性能上容易出问题。

多继承可以认为是C++的缺陷之一,很多后来的语言都没有多继承,如Java。

二、继承和组合

继承与组合都是用于描述类之间的关联关系的。

继承:继承是一种"is-a"的关系,表示一个类从另一个类派生而来,每个派生类对象都是一个基类对象。

组合:组合是一种"has-a"的关系,表示一个类包含另一个类的对象作为成员变量。通过组合,一个类可以使用另一个类的功能,但不会继承其属性和方法。

在不同的情境下,俩类之间设为继承关系还是组合关系好呢?下面用例子来说明。

//继承
class Car{……
};
​
class BMW : public Car{   //宝马is a car,这俩构成继承关系……
};
//组合
class Tire{……
};
​
class Car{   //car has a tire,这俩构成组合关系Tire _t;……
};  

通过这俩例子,可见用继承还是组合,得去判断是"is a"还是"has a",如果前者,就用继承;后者就用组合;两个都行,那就优先用组合。优先使用组合,而不是继承。

这里说明下 优先用组合 的原因:

继承是一种白箱复用。所谓白箱复用,就是透明可视化的一种复用,父类的内部细节对子类可见。这在一定程度上破坏了父类的封装。

并且,父类和子类的依赖关系很强,耦合度很高。试想,假如父类的某个成员被修改了,那在所有的子类中也会遭到修改。

而组合是一种黑箱复用。黑箱复用是另一种复用风格:新的更复杂的功能可以通过组合对象来获得。这要求被组合的对象具有良好定义的接口。派生类直接拿接口来用,而不涉及它的内部实现,这保护了基类的封装性。

并且,耦合度低,代码维护性好,我修改基类的某个成员,子类并不会受影响。

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

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

相关文章

古埃及金字塔的修建

从理论上说&#xff0c;古埃及人完全有能力设计并建造出充满各种奇妙细节的胡夫金字塔&#xff0c;但后世还是不断涌现出质疑之声&#xff0c;原因倒也简单&#xff0c;那就是胡夫金字塔实在太大了。据推算&#xff0c;整座金字塔使用大约230万块巨石&#xff0c;总质量可达约5…

通俗易懂的spring Cloud;业务场景介绍 二、Spring Cloud核心组件:Eureka 、Feign、Ribbon、Hystrix、zuul

文章目录 通俗易懂的spring Cloud一、业务场景介绍二、Spring Cloud核心组件&#xff1a;Eureka三、Spring Cloud核心组件&#xff1a;Feign四、Spring Cloud核心组件&#xff1a;Ribbon五、Spring Cloud核心组件&#xff1a;Hystrix六、Spring Cloud核心组件&#xff1a;Zuul七…

MySQL 8 手动安装后无法启动的问题解决

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;&#xff08;…

Dockerfile讲解

Dockerfile 1. 构建过程解析2. Dockerfile常用保留字指令3. 案例3.1. 自定义镜像mycentosjava83.2. 虚悬镜像 4. Docker微服务实战 dockerfile是用来构建docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 dockerfile定义了进程需要的一切东西&…

python之pyqt专栏6-信号与槽2

上一篇python之pyqt专栏5-信号与槽1-CSDN博客&#xff0c;我们通过信号与槽实现了点击Button&#xff0c;改变Label的文本内容。可以知道 信号是在类中定义的&#xff0c;是类的属性 槽函数是信号通过connect连接的任意成员函数&#xff0c;当信号发生时&#xff0c;执行与信号…

14 网关实战:网关聚合API文档

上节课介绍了网关层的认证鉴权,今天这节介绍一下网关层如何聚合API接口文文档。 为什么需要聚合API接口文档? 大型微服务系统模块众多,木谷博客系统就有9个,如果这些服务的接口地址没有一个统一,那么客户端将要保存每个服务的接口地址,这个肯定是不现实。 先来看一下A…

图书管理系统源码,图书管理系统开发,图书借阅系统源码四TuShuManager应用程序MVC控制器Controllers

Asp.net web应用程序MVC之Controllers控制器 Controller在ASP.NET MVC中负责控制所有客户端与服务器端的交互,并且负责协调Model与View之间的数据传递,是ASP.NET MVC的核心。 撰写Controller的基本要求: 1、Controller必须为公开类别; 2、Controller名称必须以Controller结…

【算法优选】 动态规划之路径问题——壹

文章目录 &#x1f38b;前言&#x1f38b;[不同路径](https://leetcode.cn/problems/unique-paths/)&#x1f6a9;题目描述&#xff1a;&#x1f6a9;算法思路&#xff1a;&#x1f6a9;代码实现 &#x1f38b;[不同路径二](https://leetcode.cn/problems/unique-paths-ii/desc…

Go 基本语法

一、​​​​变量定义方法 var 定义变量 var 变量名 类型 表达式 var name string "Snail" var age int 21 var isOK bool bool 2.类型推导方式定义变量 a 在函数内部&#xff0c;可以使用更简略的: 方式声明并初始化变量**注意&#xff1a;**短变量只能用于声…

kaggle使用matplotlib画图中文乱码问题解决

import matplotlib import matplotlib.pyplot as plt myfont matplotlib.font_manager.FontProperties(fnamer/kaggle/input/flux-predict/STFANGSO/STFANGSO.TTF) train_corr df_train.corr() k 6 cols train_corr.nlargest(k,4G流量MB&#xff08;1024&#xff09;(兆字…

什么是可重入锁

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

2023最全的自动化测试入门基础知识(超详细~)

1)首先&#xff0c;什么是自动化测试&#xff1f; 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常&#xff0c;在设计了测试用例并通过评审之后&#xff0c;由测试人员根据测试用例中描述的过程一步步执行测试&#xff0c;得到实际结果与期望结果的比较。…

pdf加密文件解密(pdf文件解密小工具)

工具放在文章末尾&#xff01; 1.pdf文件加密后会有很多使用权限的限制很不方便&#xff0c;只要是为了pdf的数据不被二次利用&#xff0c;未加密的pdf功能都是可以正常使用的 2.加密后的pdf使用权限会被限制部分 3.工具只能解决pdf编辑等加密情况&#xff0c;不能解决文件打…

浅谈UML的概念和模型之UML九种图

1、用例图&#xff08;use case diagrams&#xff09; 【概念】描述用户需求&#xff0c;从用户的角度描述系统的功能 【描述方式】椭圆表示某个用例&#xff1b;人形符号表示角色 【目的】帮组开发团队以一种可视化的方式理解系统的功能需求 【用例图】 2、静态图 类图&…

SpringBoot——自定义start

优质博文&#xff1a;IT-BLOG-CN 一、Mybatis 实现 start 的原理 首先在写一个自定义的start之前&#xff0c;我们先参考下Mybatis是如何整合SpringBoot&#xff1a;mybatis-spring-boot-autoconfigure依赖包&#xff1a; <dependency><groupId>org.mybatis.spr…

【总结】重极限的计算

这个做法比较严谨&#xff0c;我之前是想着分母趋于0&#xff0c;分子也得趋于0&#xff0c;这个有界量乘无穷小还是无穷小的手法还是很漂亮的。 图一源链接https://www.zhihu.com/question/269472244 图二选自李艳芳真题解析

FFmepg 核心开发库及重要数据结构与API

文章目录 前言一、FFmpeg 核心开发库二、FFmpeg 重要数据结构与 API1、简介2、FFmpeg 解码流程①、FFmpeg2.x 解码流程②、FFmpeg4.x 解码流程 3、FFMpeg 中比较重要的函数以及数据结构①、数据结构②、初始化函数③、音视频解码函数④、文件操作⑤、其他函数 三、FFmpeg 流程1…

福利来了| 200多款精选简历模板免费领,让你30秒内征服HR!

找工作是不是让你很头大&#xff1f;尤其是写简历&#xff0c;真的好痛苦啊&#xff01;我在网上找了好久&#xff0c;都没有找到合适的简历模板&#xff0c;自己做又不知道从哪里下手。 不过现在好了&#xff0c;有一个超级福利送给大家&#xff01;200多款精选简历模板免费领…

使用HTML+CSS+JS网页设计与制作,酷炫动效科技农业网页

使用HTMLCSSJS网页设计与制作&#xff0c;酷炫动效科技农业网页。 可以用于家乡介绍、科技农业、图片画廊展示等个人网站的设计与制作。农业网站、家乡网站、农产品网站、旅游网站。 网站亮点 1、视觉设计&#xff1a;排版布局极简设计&#xff0c;优质的视觉体验等。 2、动…

手摸手Element-ui路由VueRoute

后端WebAPI准备 https://router.vuejs.org/zh/guide/ https://v3.router.vuejs.org/zh/installation.html <template><el-table:data"tableData"style"width: 100%":row-class-name"tableRowClassName"><!-- <el-table-colum…