继承【C++】

继承【C++】

  • 一.什么是继承?
  • 二. 继承的方式与权限
  • 三. 继承中的成员
    • 3.0 基类和派生类中的重名成员
      • i. 限定符
      • ii. 隐藏
    • 3.1 继承与默认成员函数
      • i. 默认构造
      • ii. 析构函数
    • 3.2 继承与友元函数
    • 3.3 继承与静态成员变量
  • 四. 基类和派生类的赋值
  • 五. 多继承
    • 5.1 菱形继承
    • 5.2 菱形模拟继承
  • 六. 继承的总结
    • i. 能用多继承就不要用菱形继承
    • ii. 能用单继承就不要用多继承
    • iii.能用组合就不要用继承


一.什么是继承?

继承听名字大家可能就知道它是什么意思了
但是不知道继承的对象和内容是什么?
这时候告诉大家继承是用在类和类的

那这个时候应该都清楚继承是干嘛用的了

类如果继承了一个类,那能继承什么呢?
类中的内容:成员函数和成员变量

所以这里想都不用想就知道继承的是类中的函数和变量。

这里被继承的类叫做:基类
继承后的新类叫做:派生类

派生类拿到的是基类的成员的使用权

二. 继承的方式与权限

上面我们知道了继承的具体对象,那接下来就是该如何继承了

最普通的格式就是:
在这里插入图片描述

上面就是派生类child继承了基类parent

这里我们能看到public
这个public就是继承方式

我们都清楚:
类的成员中都有成员变量的访问权限,用来控制外界对类中成员的访问权限

在这里插入图片描述
那既然有访问限定符能控制类中的成员的外界访问权。

那有没有一种方法来控制派生类对基类继承成员的访问权限。

实现这个作用的就是我们的继承方式了

在这里插入图片描述

这里用了一张表格来表示了
不同权限的基类在用对应的继承方式后在派生类的权限

这里其实也不用记得特别牢
因为品尝我们使用时基本上都是public继承
但是要记的话也很简单:
1. private让所有成员不可见
2. 其他访问方式都是取决于访问方式和类本身权限的大小,谁小取谁

这里我们能了解到private与protected的区别了
没学继承前,我们都把private和protected看成一样的。

但是现在我们能了解到它们的区别了

在这里插入图片描述

这里我们发现这个c变量报错了

这就能看出区别了:
private继承后不能被派生类以及其他类访问
protect继承后能被派生类访问,但是不能被其他类访问

这里还有个小细节,不知道大家发现没有:
这里的private继承方式写的是不可见:
这里我们应该就能想到:
private的继承方式,并非是继承时不带上其他成员,而是派生类中带上了基类成员,但是不可访问而已

三. 继承中的成员

我们知道了继承是一个了类继承一个类的成员函数和成员变量

但是还是有一些细节的,因为成员变量和成员函数也有很多不同的类型。

3.0 基类和派生类中的重名成员

在这里插入图片描述
这两个重命名变量,这里我们进行一下打印

在这里插入图片描述
这里优先的是派生类中的a

这里其实和全局变量和局部变量重命名打印一样
遵从的是就近原则

我们都知道类有自己的类域
所以同时这里要注意:派生类和基类这里都有各自的类域

i. 限定符

因为派生类和基类有各自的类域

所以这里想要访问基类中的a
这里就可以用访问限定符。

在这里插入图片描述
这里我们就能发现结果是1了
在这里插入图片描述

ii. 隐藏

不光是变量能重名,函数同样也能重名。
在这里插入图片描述
按以前来来说当函数名不一样,这个时候就是重载
但是这个看起来就和重载不一样

因为重载当初的有两点:
1.必须要在同一个域中
2.函数参数列表不同

那这里换个情况
在这里插入图片描述
这里两个类的函数参数列表不同,那这样算不算是函数重载

这里肯定是否定的,因为这样就不符合在同一个域中的条件。

那这样不算是重载,那算是什么情况。

这个就是全新的情况了:隐藏

隐藏的条件如下:
1.成员名重名
2.处于不同类域中。

3.1 继承与默认成员函数

默认成员函数可以说是类都会调用的函数

当派生类继承基类后,对类进行实例化时
调用派生类的构造函数时,会自动去调用父类的构造和析构函数

因为派生类继承了父类的成员
所以派生类进行实例化的时候,基类同样也要进行实例化。
因为父类的成员也需要去定义

但是这里要注意,派生类继承基类的成员函数时
和基类是公用一个成员函数的,但是传this指针时,还是看类的类型

所以这里就来研究一下不管什么类实例化都需要走的默认构造和析构

i. 默认构造

这里我们先来测试一下子类会不会去调用父进程的构造函数

在这里插入图片描述

在这里插入图片描述
这里就能清楚的看出来子类调用了父类的构造函数。

同时我们能发现父类比子进程要先进行实例化

这里还有种情况:如果父类没有合适的构造函数该怎么办:
在这里插入图片描述
这里能发现报的错是父类不存在默认构造函数

那这里我们想用参数给父类传参进行构造该怎么办?

这里我们就可以在子类构造函数的初始化列表中传入给父类构造的参数。

这是c++语法设计的。

ii. 析构函数

接下来除了构造接下来第二个大头就是析构函数了

因为我们也清楚既然派生类会先自动调用父类的构造函数
那这样也会自动去调用父类的析构函数
所以我这里只要知道执行的先后顺序即可:

在这里插入图片描述

在这里插入图片描述
这里我们就能够看出
基类要后进行析构

这样设计正好符合了先定义的要后进行析构
因为如果先定义的先进行析构了,这样的话如果还有其他成员在使用,就会产生问题。

3.2 继承与友元函数

这里其实一句话就能讲清楚:

父类的友元关系不会继承到派生类中。

3.3 继承与静态成员变量

要了解这两个的关系

首先我们要清楚子类继承的是父类成员中的使用权
所以子类继承父类中的静态成员的使用权后,不再需要去定义

因为父类成员中已经定义过一次了,静态成员只会定义一次

这样也能解决一个问题:检测父类被继承了多少次

在这里插入图片描述

创建一个静态成员变量,在父类的构造函数中赛个++就可以了。
因为子类实例化都会去调用父类的构造函数。
在这里插入图片描述

四. 基类和派生类的赋值

这里我们要注意一个父类和基类能够进行赋值运算

这里我 们其实想想也知道是派生类能赋值给基类。

因为基类有的
因为派生类中有很多的基类中的内容
但是基类没有派生类中的成员。

五. 多继承

多继承这里就造成了一个C++中的一个巨坑
其实java中或者其他语言都不支持多继承。
就是看到了其中的坑,具体坑在哪,接下来就来看看。

首先是多继承,顾名思义,就是一个类继承了多个类。

在这里插入图片描述
这里的子类就继承了father类和mom类

这里看起来好像很正常没有坑的样子,但是换种别的继承方式,就有坑了。

5.1 菱形继承

这个就是多继承中的天坑了

这里先直接上代码

class people 
{
public:
int a;

};

class father : public people
{
public:

	~father()
	{
		std::cout << "father\n";
	}
};
class mom : public people 
{

};


class child : public father ,public mom
{
public:
	~child()
	{
		std::cout << "child\n";

	}
};

这里或许可能还有人看不出来
这里就直接上个示意图
在这里插入图片描述
大致就是这样的一个继承关系
这样我们就能很方便的看出来是个菱形了
这里我们也能看到这里最大的问题不是继承了父母

而是父母共同继承了people

这里是结构图
在这里插入图片描述

这里我们也从底层验证一下:

class people 
{
public:
	int people;

};

class father : public people
{
public:
	int father;
};
class mom : public people 
{
public:
	int mom;
};


class child : public father ,public mom
{
public:
	int child;
};

int main()
{
	child c1;
	c1.child = 0;
	c1.father = 1;
	c1.mom = 2;
	c1.father::people = 3;
	c1.mom::people = 4;
}

在这里插入图片描述
这里能看出这里的内存按照需求进行了排列

这样子会带来两个问题:
1.数据冗余
有两个people类(重点是这个问题)
2.访问不清
(这个其实还好,用限定符就可以解决)

5.2 菱形模拟继承

所以C++为了填坑,特意出了菱形模拟继承

专门用来解决这个多继承的坑。

class people 
{
public:
	int people;

};

class father :virtual public people
{
public:
	int father;
};
class mom : virtual public people
{
public:
	int mom;
};


class child : public father ,public mom
{
public:
	int child;
};

int main()
{
	child c1;
	c1.child = 0;
	c1.father = 1;
	c1.mom = 2;
	c1.father::people = 3;
	c1.mom::people = 4;
}

使用方法:
在两个类都需要的类继承时添加上virtual即可
在这里插入图片描述

这里我们就来看看它的变化
(接下来用了32位,但其实没有啥大区别)
在这里插入图片描述

这里发现原本的在father和mom中的people
到了最底下,并且只有一个值了

这就是虚拟继承干的事了

mom和fahter共同继承的people变成了公有类
塞在了类的最下方

这里明眼人可能已经看到了
在这里插入图片描述
mom和father类中多了这样两个数据
而且只有最前面的数据不一样

其实这里是通过了B和C的两个指针
指向的一张表。这两个指针叫虚基表指针

而指向的一个表则是虚基表

虚基表中存的偏移量能帮助father和mom找到people类。

这里可以来验证一下
在这里插入图片描述

在这里插入图片描述
这里能看到虚基指针指向的虚基表中的偏移量是14

这样完美解决了多继承中的数据冗余的问题

六. 继承的总结

这里讲完了继承的用法与细节,这里就来总结一下继承的用法

i. 能用多继承就不要用菱形继承

菱形继承我们也知道了它的坑有多大,所以能不用最好不用

ii. 能用单继承就不要用多继承

iii.能用组合就不要用继承

这里的组合就是指
在这里插入图片描述
就是将类和类进行组合

用这个对比继承有两个好处:
1.保留了类的封装性
2.低耦合性

第一点很好理解
继承后,能使用类中的成员,而组合则是使用这个类的对象。

第二点的耦合性是什么意思?
其实也很好理解
耦合可以看作是粘黏性,也可以说是相关性

比如继承中,如果继承的基类成员发生了改变
那么派生类中的也发生了改变,因为派生类很有可能引用了基类中的成员
所以当我们在开发时,修改了基类,就要去修改一大堆继承它的派生类。
所以这是很不利于开发的。

所以组合来说,只是引用了它的类对象。

所以关联性不是很大。

所以我们尽量使用低耦合的开发模式。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CFCA证书——基于SM2/3算法的安全信任

在中国金融认证中心&#xff08;CFCA&#xff09;发行的证书中&#xff0c;采用了最新的国密SM2/3算法来提供更高的安全保障。这一创新举措进一步增强了我国网络安全能力&#xff0c;并为用户提供了一种更可靠、更安全的选择。 SM2/3算法是中国自主研发的非对称加密算法&#…

瑞格心理咨询系统设置多个管理员的操作方法

使用瑞格心理咨询系统&#xff0c;需要设置多个admin权限的管理员账号来管理&#xff0c;咨询厂家答复只能有1个管理员&#xff0c;个人觉得不可能&#xff0c;于是开始折腾。 解决办法&#xff1a; 在没有数据字典的情况下&#xff0c; 通过遍历数据库&#xff0c;发现用户信…

python趣味编程-5分钟实现一个石头剪刀布游戏(含源码、步骤讲解)

Python 中的石头剪刀布代码是 使用Tkinter和图形用户界面(GUI)设计的。 Python 石头剪刀布游戏是使用Python 编程语言开发的简单桌面应用程序。 项目系统文件包含资源文件和Python脚本。游戏画面流畅,用户控制起来很容易。

大数据:SAS数据分析1,数据步,和过程步

大数据&#xff1a;SAS数据分析 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sql…

2023年DevOps国际峰会暨BizDevOps企业峰会(DOIS北京站)-核心PPT资料下载

一、峰会简介 在数字化转型的大背景下&#xff0c;企业选择实践 DevOps 来提升 IT 效能成为常态&#xff0c;BizDevOps 作为企业自身数字化变革的重要主题之一&#xff0c;需要全行业共同努力促进繁荣和发展。从 DevOps 到 BizDevOps&#xff0c;业务与技术如何融合&#xff1…

JAVAEE---多线程

内核 内核时操作系统的核心 操作系统有内核态和用户态&#xff0c;像我们平时所用到的qq音乐&#xff0c;微信等都属于用户态执行的程序。那么qq音乐播放音乐需要用到扬声器&#xff0c;扬声器的操作就是在内核空间进行操作&#xff0c;用户态不能对其进行操作。 操作系统 …

移远通信推出六款新型天线,为物联网客户带来更丰富的产品选择

近日&#xff0c;移远通信重磅推出六款新型天线&#xff0c;覆盖5G、非地面网络&#xff08;NTN&#xff09;等多种新技术&#xff0c;将为物联网终端等产品带来全新功能和更强大的连接性能。 移远通信COO张栋表示&#xff1a;“当前&#xff0c;物联网应用除了需要高性能的天线…

基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码

基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于卷尾猴优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络…

雷电模拟器报错:g_bGuestPoweroff.fastpipeapi. cpp_1153_1161

文章目录 一、报错详情&#xff1a;二、解决&#xff1a;【1】设置Windows功能【2】设置cmd&#xff08;管理员身份&#xff09;【3】重启电脑 三、windows10其中1809版本出现1153、1161&#xff0c;需要关闭内核隔离 一、报错详情&#xff1a; 二、解决&#xff1a; 【1】设置…

909-2014-T2

文章目录 1.原题2.算法思想3.关键代码4.完整代码5.运行结果 1.原题 二叉树采用二叉链表存储结构&#xff0c;设计算法&#xff0c;判断二叉树是否为满二叉树。叙述算法思想并给出算法实现。 2.算法思想 通过一次遍历&#xff0c;得到结点个数和树的高度。用结点个数和树的高…

什么是高防CDN?有什么优势?

德迅高防CDN技术概述 随着互联网的快速发展&#xff0c;网络安全问题越来越受到人们的关注。高防CDN(Content Delivery Network)作为一种有效的网络安全防御手段&#xff0c;在企业和个人网站中得到了广泛应用。本文将详细介绍高防CDN的技术原理、防御原理、优点和应用场景&am…

TransmittableThreadLocal - 线程池中也可以传递参数了

一、InheritableThreadLocal的不足 InheritableThreadLocal可以用于主子线程之间传递参数&#xff0c;但是它必须要求在主线程中手动创建的子线程才可以获取到主线程设置的参数&#xff0c;不能够通过线程池的方式调用。 但是现在我们实际的项目开发中&#xff0c;一般都是采…

用 HLS 实现 UART

用 HLS 实现 UART 介绍 UART 是一种旧的串行通信机制&#xff0c;但仍在很多平台中使用。它在 HDL 语言中的实现并不棘手&#xff0c;可以被视为本科生的作业。在这里&#xff0c;我将通过这个例子来展示在 HLS 中实现它是多么容易和有趣。 因此&#xff0c;从概念上讲&#xf…

秋招JAVA面经总结

面试的范围是Java基础+Java并发+Java框架+mysql+网络。 Java基础 重载与重写有什么区别? 重载(Overloading)指的是在同一个类中,可以有多个同名方法,它们具有不同的参数列表(参数类型、参数个数或参数顺序不同),编译器根据调用时的参数类型来决定调用哪个方法。 重写…

会声会影2024出来了吗?会声会影2023怎么使用?

会声会影20247中文旗舰版 Corel VideoStudio 是一款功能强大的视频编辑软件&#xff0c;可以帮助用户创建高质量的视频作品。它提供了一系列完善的编辑功能&#xff0c;包括视频编辑、音频编辑、调色、特效、字幕、标题等。它还支持多种视频格式&#xff0c;可以将视频转换为多…

CSDN专栏设置

文章目录 一、规则1.1、专栏数量与等级关联1.2、等级与积分关联1.3、积分1.3.1、积分获取1.3.2、积分被扣 二、配置2.1、入口2.2、新建2.2.1、一级专栏2.2.2、二级专栏 2.3、快捷编辑2.4、拖拽 一、规则 写了一阵子CSDN博客后&#xff0c;发现自己新增专栏的时候提示不能再新增…

Linux调度域与调度组

引入调度域的讨论可以参考这篇文章。这篇笔记重点分析了内核调度域相关的数据结构以及内核用于构建调度域的代码实现&#xff0c;以此来加深对调度域的理解。调度域是调度器进行负载均衡的基础。 调度域拓扑层级 整个系统的调度域组成一个层级结构&#xff0c;内核设计了stru…

909-2015-T2

文章目录 1.原题2.算法思想3.关键代码4.完整代码5.运行结果 1.原题 编写算法&#xff0c;删除二叉搜索树&#xff08;二叉排序树&#xff09;的最小元素。叙述算法思想并给出算法实现&#xff0c;分析算法复杂性。二叉树采用链式存储结构&#xff0c;节点结构如下&#xff1a;…

编写函数求定积分的通用函数

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 不积跬步无以至千里&#xff0c;…

子虔科技亮相2023工业软件生态大会 以先进理念赋能工业软件发展

作为云化工业软件领先企业&#xff0c;子虔科技携多项全新云原生产品亮相2023工业软件生态大会。 本届大会以“共建新一代工业软件体系&#xff0c;引领制造业高质量发展”为主题&#xff0c;集结行业领先企业、行业专家探究工业软件在核心技术、产业链创新和生态建设等方面创…