【C++笔记】C++继承

news2024/12/28 20:44:09

【C++笔记】C++继承

  • 一、继承的概念
  • 二、继承的语法和权限
  • 三、父类和子类成员之间的关系
    • 3.1、子类赋值给父类(切片)
    • 3.2、同名成员
  • 四、子类中的默认成员函数
    • 4.1、构造函数
    • 4.2、拷贝构造
    • 4.3、析构函数
  • 五、C++继承大坑之“菱形继承”
    • 5.1、什么是“菱形继承”
    • 5.2、解决方法

一、继承的概念

继承:

继承是面向对象编程中的一个重要概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。继承是一种代码重用的方式,它可以减少代码的重复,提高代码的可维护性和可扩展性。
继承的基本原理是子类可以使用父类的属性和方法,而不需要重新编写代码。子类可以继承父类的公共属性和方法,也可以重写父类的方法或添加新的属性和方法。这种机制使得子类可以扩展父类的功能,同时保留父类的特性。

用一个简单的例子演示一下:
在这里插入图片描述
这里B继承了A,B不仅可以访问自己的成员变量,也可以访问自己父类的成员变量和成员函数。

二、继承的语法和权限

继承的语法格式如下:

class 子类名字:继承方式 父类名字{};

子类继承父类的继承方法有三种:

public
protected
private

(protected修饰的成员在内里边可以使用,在类外边不可以使用)
不同的修饰方法会使得子类中的父类成员权限不同,而且父类中以不同权限修饰符修饰的成员在继承到子类后的权限也会不同。
比如最简单的以public的方式继承:
在这里插入图片描述
public继承方式可以访问到父类中public的成员。
而如果是父类中的private成员就不行了:
在这里插入图片描述

还有其他的组合如下表:
在这里插入图片描述
有人可能会觉得这张表好复杂,觉得要背下来的话一定很困难。
其实我们并不需要去背这张表,我们仔细观察这张表之后就会发现其中的规律。
因为最后一个行都是不可见,我们可以把最后一行特殊化处理,然后剩下的我们仔细观察后就会发现,表中的任何一个结果都可以总结为:

min(父类中的修饰符,子类的继承方式)
在这里插入图片描述

三、父类和子类成员之间的关系

3.1、子类赋值给父类(切片)

因为子类继承了父类的成员,所以子类也可以看作是一种特殊的父类。那么将子类对象赋值给父类对象会怎么样呢?
在这里插入图片描述
我们发现父类自己的成员还是可以正常访问的,可若要是想访问子类的成员就不行了:
在这里插入图片描述
这样想跟我们平时理解的赋值不一样啊。

其实它在底层执行了一个“切片”操作:
在这里插入图片描述

因为父类中没有_id,所以父类并不会接收子类的_id,父类之后接受自己有的成员的值。
所以子类自己独有的成员也就被“切”掉了。

其他的赋值方式例如引用:
在这里插入图片描述
引用我们可以理解为,父类的引用只引用了子类中属于父类的那一部分。

指针:
在这里插入图片描述
指针其实是并不存在“切片”操作的,只需要执行子类的首地址即可,因为这是Person类型的指针,而指针能访问到的范围其实是由指针类型已经决定了的。
所以父类的指针只会访问到子类中属于父类的成员。

3.2、同名成员

同名成员变量:

有时候父类和之类中会存在一些同名成员变量,比如name:
在这里插入图片描述
这时候编译器会议子类的成员优先。
如果真要想访问到父类的就得要加上域作用限定符,限定为访问父类的:
在这里插入图片描述
同名成员函数:
如果父类和子类之中存在同名函数又会怎么样呢?
在这里插入图片描述
这其实就构成了“隐藏”,并不是函数重载,函数重载一定要是在同一作用域,而两个类之间并不是同一个作用域,即使他们之间是继承关系。
隐藏的条件是只需要函数名相同,对参数列表和返回值都没有要求。
这时候编译器还是会优先选择子类的函数,这也称之为父类的函数被子类的函数隐藏了。
这时候如果想要调用父类的,也需要加上域作用限定符:
在这里插入图片描述

四、子类中的默认成员函数

4.1、构造函数

我们来看看,继承关系中的构造函数会怎么做:
在这里插入图片描述

如果创建一个子类对象,编译器会先调父类的构造函数再调用子类的构造函数。

这其实是编译器自动调用的,即使我们没有显示的写出子类的构造函数,编译器也会自动去调用父类的构造函数:
在这里插入图片描述

而如果我们想要在子类中显示的构造父类对象,就必须将父类对象当成一个整体(当成一个对象)去构造,即调用父类的构造函数:
在这里插入图片描述
记住一定要在初始化列表处调用,不然就会存在父类构造被调用两次的问题:
在这里插入图片描述
这是因为编译器默认就会在初始化列表中调用父类构造函数。

而我们不能想当然的像下面这样初始化父类:
在这里插入图片描述
这是规定!

4.2、拷贝构造

拷贝构造也是要先调用父类的再调用子类的:
在这里插入图片描述
再构造函数中我们可以直接将子类对象传递给父类的构造函数,因为父类会通过“切片”操作拿到子类中父类的部分。

4.3、析构函数

析构函数和构造函数正好相反,析构要求的是先调用子类的析构再调用父类的析构。
在这里插入图片描述
而如果我们在子类的构造函数中显示的调用父类的构造函数就会发生调两次析构的危险:
在这里插入图片描述
而析构函数调用两次是很危险的,这很有可能就会导致同样的资源被释放两次的错误。

其实这是因为父类的析构函数是编译器自动调用且是在子类析构结束后才调用的,所以也就决定了它不能像构造函数一样写在初始化列表里。
也就不能自己调用,只能由编译器调用。

五、C++继承大坑之“菱形继承”

因为C++时出现的比较早的面向对象的语言,也就没有多少其他的面向对象语言可以参考,所以许多面向对象的“坑”也就避免不了了。
其中一个坑就是今天要讲的“菱形继承”。

5.1、什么是“菱形继承”

C++是支持多继承的,也就是一个类可能会存在多个直接父类,例如下面这个例子:
在这里插入图片描述
他们之间的继承关系如下图所示:
在这里插入图片描述
而如果这些关系再复杂一点儿,就会变成“菱形继承”了:
在这里插入图片描述
在这里插入图片描述
在这样的继承状态中,处于中间的A、B两个类是没有什么问题的,问题就出在最下面的C这个类:
在这里插入图片描述
从代码中我们并不能看出问题出在哪里,我们得到监视窗口中才能看出:
在这里插入图片描述
从内存中我们可以看到c1中竟然存了两个_o(一个是A继承的,一个是B继承的),这也就是为什么报错提示访问不明确的原因。

5.2、解决方法

方法一:加类域修饰
既然两个_o一个是A继承的,一个是B继承的,那我们直接指定是哪个类的不就行了:
在这里插入图片描述

方法二:virtual虚继承
还有一种方法就是在菱形继承的“腰部”加上virtual继承:
在这里插入图片描述
简单来说就是将菱形继承中具有公共父类和公共子类的那几个类继承其公共父类的方式全都改成虚继承。

虽然说菱形继承的问题已经被解决了,但是我们最好还是不要弄出菱形继承的好,多继承是没什么问题的,但是菱形继承就是个大坑。

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

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

相关文章

为什么自学或是培训完软件测试后,找不到工作?原因可能是这几种

最近我的一个表弟想学习软件测试,但他一直在犹豫是报班还是自学,甚至担心学完后市场饱和了,学完找不到工作。那么借用这次机会,跟大家进行分析一下软件测试行业找不到工作的几个原因,希望能够帮助到大家,少…

Python(一)关键字、内置函数

程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&am…

随笔:使用Python爬取知乎上相关问题的所有回答

项目中数据分析的需要自己从知乎某个专门的问题上爬数据,但众所周知,知乎的问题的显示方式有点胃疼(指滑动后下翻加载更多回答,还经常卡住),翻了翻网上的教程发现有的要么就是很老了要么就是付费的&#xf…

ubuntu 安装 gnome 安装 xrdp

先安装xrdp 更新 apt-get sudo apt-get update && apt-get upgrade安装图形包 apt-get install xubuntu-desktop安装 xrdp apt-get install xrdp安装 xfce4 apt-get install xfce4配置 xfce4 Add xfce to the xfce desktop window manager autorun by fixing the …

静电模型PIC方法的Matlab仿真设计

任务要求: 采用PIC模拟方法的静电模型来模拟多环形电子注在圆柱系统中的运动轨迹。模拟电子枪阴极表面发射电子注,电子在静态场的作用下运动直至稳定的运动过程。其中 系统长:0.01m 系统半径:0.005m 入射的每个宏电子电流&#x…

RedHat8升级GLIBC_2.29,解决ImportError: /lib64/libm.so.6: version `GLIBC_2.29

问题背景 在做大模型微调训练时,执行python脚本时出现如下报错: 查看当前服务器版本,确实没有GLIBC_2.29的 strings /lib64/libm.so.6 | grep GLIBC_ GLIBC_2.2.5 GLIBC_2.4 GLIBC_2.15 GLIBC_2.18 GLIBC_2.23 GLIBC_2.24 GLIBC_2.25 GLIB…

Java后端开发——实现登录验证程序

一、实现一个简单登录验证程序 实现一个简单的用户登录验证程序,如果用户名是 abc ,密码是 123,则显示欢迎用户的信息,否则显示“用户名或密码不正确”。 【分析】 该案例采用 JSP 页面只完成提交信息和验证结果的显示&#xff…

零基础Linux_22(多线程)线程控制和和C++的多线程和笔试选择题

目录 1. 线程控制 1.1 线程创建(pthread_create) 1.2 线程结束(pthread_exit) 1.3 线程等待(pthread_join) 1.4 线程取消(pthread_cancel结束) 1.5 线程tid(pthread_self()) 1.6 线程局部存储(__thread) 1.7 线程分离(pthread_detach) 2. C的多线程 3. 笔试选择题 答…

百济神州:受专利侵权诉讼影响,股价暴跌,估值已被华尔街大幅下调

来源:猛兽财经 作者:猛兽财经 百济神州股价暴跌估值已被下调 今年以来,百济神州(BGNE)在美股的股价已经下跌了26.1%。在2023年10月18日的的交易日结束时,百济神州的最后最后交易价为167.54美元,与2023年1月20日的52周…

Unity DOTS系列之Filter Baking Output与Prefab In Baking核心分析

最近DOTS发布了正式的版本, 我们来分享一下DOTS里面Baking核心机制,方便大家上手学习掌握Unity DOTS开发。今天给大家分享的Baking机制中的Filter Baking Output与Prefab In Baking。 对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础…

优化单元测试效率:Spring 工程启动耗时统计

相关文章: Java Agent 的简单使用 本文相关代码地址:https://gitee.com/dongguabai/blog 单元测试在软件项目的可持续发展中扮演着不可或缺的角色,这一点毫无疑问。不久前,公司大佬在内部分享时也提到过:单元测试是…

“动捕设备+飞兔渲染软件”,激发数字人短视频营销新动力

随着短视频行业持续破发,短视频成为目前吸引流量最快的方式之一。同时,元宇宙催生众多虚拟主播、虚拟偶像、虚拟IP等,以数字人形象结合短视频形式,在社交平台上频频出圈。如虚拟美妆达人“柳夜熙”一条视频涨粉150w,但…

[卷积神经网络]FasterNet论文解析

一、概述 FasterNet是CVPR2023的文章,通过使用全新的部分卷积PConv,更高效的提取空间信息,同时削减冗余计算和内存访问,效果非常明显。相较于DWConv,PConv的速度更快且精度也非常高,识别精度基本等同于大型…

【计算机网络(1)】计算机网络体系结构1:计算机网络概述

文章目录 概念 & 功能 & 发展计算机网络的概念计算机网络的功能计算机网络的发展网络的本质 组成 & 分类计算机网络的组成计算机网络的分类 概念 & 功能 & 发展 计算机网络的概念 1. 网络 网一样的东西或网状系统。其中(有线电视网络、电信网…

亲测解决no module named ‘PyQt5.QtCore‘

如果是在windows上遇到这个问题,升级一下VS Studio即可。 运行坏境和问题 Win10 Anaconda 解决方法 升級vs studio from 2022 preview to 2022。

springboot配置注入增强(四)使用框架实现自定义数据源和自定义属性解析

1.代码 框架代码已经上传到gitee中 代码链接:https://gitee.com/summer-cat001/config-enhance jar包:https://gitee.com/summer-cat001/config-enhance/tree/master/build/libs 2.使用方式 2.1 引入jar包 引入本地jar包或者把jar包上传到自己的ma…

年薪20w+,做测试的第4年,从手工测试到自动化测试每一步都是艰难的~

自己已经做了好几年的手工测试了,越来越觉得如果一直在手工测试的道路上前进,并不会有很大的发展,所以通过自己的努力,已经成功的转入自动化测试的方向,那么想快速的转入自动化方向,我们应该怎么做呢&#…

Linux的命令基本格式

因为对服务器来讲,图形界面会占用更多的系统资源,而且会安装更多的服务、开放更多的端口,这对服务器的稳定性和安全性都有负面影响。其实,服务器是一个连显示器都没有的家伙,要图形界面干十么?说到这里&…

python—openpyxl操作excel详解

前言 openpyxl属于第三方模块,在python中用来处理excel文件。 可以对excel进行的操作有:读写、修改、调整样式及插入图片等。 但只能用来处理【 .xlsx】 后缀的excel文件。 使用前需要先安装,安装方法: pip install openpyxl…

基于二维小波变换的散斑相位奇异构造算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 图(1)表示散斑原图像,(2)表示对(1)图像进行x轴方向的极化分析的小波相位图,呈周期的水平条纹,(3)表示对(1)图像…