【C++】继承(上)(超详细,保证你学会)

什么是继承?

1.语法

1.1例子

通过这种方法,Student和Teacher这两个类就继承了Person的成员变量和成员函数,可以直接调用它们。

如图,如果成员变量和成员函数在基类中是公有的话就可以直接访问!但如果是私有和保护的话就无法访问。

1.2继承基类成员访问方式的变化

1.先看这个表格的最后一行,只要在基类中是私有成员,不论哪种继承方式,在派生类中均不可见。这里的不可见不是说真的不可见,而是在派生类外边和里边不可以直接访问,但是派生类可以通过基类中公有成员函数访问。(注意,不论是成员函数还是成员变量都是成员,如果它们是私有,都不能直接在类外面访问,只能通过其他公有的成员函数访问)。

2.另外两行需要记住一个规则(权限:public>protected>private)。记住这个规则后,在继承过程中,最终结果去权限小的那一个。

比如,基类的protected成员被派生类public继承后,由于protected权限小于private,所以基类的protected成员在派生类中依然是保护成员。

再比如,基类的protected成员被派生类private继承后,由于protected权限大于private权限,所以基类的protected成员在派生类中变成private成员。

1.2.1protected和private的区别

解释一下,基类中的private成员不光在基类和派生类外面不能访问,而且派生类里面也不能访问。

而基类中的protected成员,在基类和派生类外面不能访问,但在派生类里面可以被访问。

熟悉继承的语法后就可以理解,其实实践中用得最多的直接上面的一小部分。因为继承的意义在于派生类能够顺畅的使用基类的成员,所以protected继承和private继承就极少用到。所以我们在日常的学习甚至工作中记住上面这个小表格就足够了。

再补充一下,struct也可以继承,但要注意与class的区别。

1.class的默认访问限定符是private,在没写继承方式时,继承方式同样默认private继承。‘

2.struct的默认访问限定符是public,在没写继承方式时,继承方式同样默认public继承。

虽然它们有默认的访问限定符和默认的继承方式,但还是建议写上,一是格式更加标准,二是提高代码的可读性。

2.基类和派生类对象赋值转换

在派生类对象对基类对象赋值时,不会产生临时对象,所以在传引用时不用加const(可以理解为编译器的特殊处理)。但是基类对象不可以赋值给派生类对象。

赋值兼容,编译器进行特殊处理。

这是is -a的关系,就把派生类和基类当成一个类型,在赋值过程中没有类型的转换就不产生临时对象。所以传引用和传指针时,通过派生类改变成员变量,基类中的也会随之改变。

因为基类的对象的成员变量派生类中都有,所以在赋值时,相当于在把派生类中含有基类成员变量的部分进行切片然后赋值给基类。传指针时,基类的指针同样指向该切片的空间。所以在传引用和指针后,对基类的成员变量修改,会让派生类对应的成员变量发生改变。

派生类中的内置类型成员直接赋值给基类,自定义类型成员调拷贝构造给基类。

3.继承中的作用域

学到现在,一共有几个域的概念:

1.局部域 2.全局域 3.命名空间域 4.类域

局部域和全局域会影响访问也会影响声明周期(同一个域不能有同名变量和同名函数,不同的域可以同名),类域和命名空间域只影响访问不影响声明周期。

在类域中又可以细分为基类的类域和派生类的类域。

基类和派生类可以有同名的成员变量,在访问时遵循“就近原则”。在派生类访问时,默认访问派生类的,如果想访问基类的,需要域作用限定符。

3.1练习一下

这个题目的正确答案是D。

对于C:两个函数构成重载的前提是:1.在同一个域中。2.函数命相同。3.参数不同。所以C不对。

公有继承后,在派生类里面,同名函数这样访问:

在派生类外面,同名函数这样访问:

把基类成员当成一个整体,把它们看成一个自定义类型。派生类成员还是和以前一样。

在派生类对象实例化时,会调用父类的默认构造函数,如果没有,编译报错。

回顾一下类和对象中的构造函数:

在对象实例化时,编译器默认生成的构造函数对于成员变量中的内置类型(int char等)不做处理,对于自定义类型(vector string等),去调用它们自己的默认构造。

关于构造函数

如果基类没有默认构造函数,编译报错:

除非在派生类的构造函数中显式的调用基类的构造函数:

当然如果基类中有默认构造函数,就不需要在派生类的构造函数中显式的调用基类的构造函数了:

类比:

如果不用继承,就把Person当成BB的成员,在Person没有默认构造时,同样需要在BB的构造函数中显式的调用Person的构造函数,区别就是继承类似于匿名对象的初始化,这个是有名的。

因此,继承,你就可以想象成有一个基类对象变成了派生类的成员,所以它是一个整体,它的初始化只能去调它的构造函数,不可以在派生类的构造函数中逐一初始化它的成员。

关于拷贝构造:

对于派生类调用编译器默认生成拷贝构造时,对于内置类型进行值拷贝。对于自定义类型(vector,string)调用它们的拷贝构造,对于基类(也是自定义类型),也是调用基类的拷贝构造。(所以一般派生类中编译器默认生成的拷贝构造是够用的)。

假设需要显示的写拷贝构造:

这是基类的拷贝构造。

这是派生类的拷贝构造(借用了基类的拷贝构造,利用了切割/切片)。

关于赋值:

派生类调用赋值时(编译器默认生成的),对于内置类型直接赋值,对于自定义类型(包括基类)回去调用它们的赋值。

如果显示的写,如下:

对于析构函数:

派生类的析构会隐藏基类的析构,需要基类的访问限定符才能访问到基类的析构。

构造要求先父后子,析构要求先子后父。

因此:

所以:

在派生类的析构函数中不要手动调用基类的析构函数,否则基类会析构两次!

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

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

相关文章

SpringAMQP Work Queue 工作队列

消息模型: 代码模拟: 相较于之前的基础队列,该队列新增了消费者 不再是一个,所以我们通过代码模拟出两个consumer消费者。在原来的消费者类里写两个方法 其中消费者1效率高 消费者2效率低 RabbitListener(queues "simple.queue")public voi…

Arduino-ILI9341驱动开发TFT屏显示任意内容三

Arduino-ILI9341驱动开发TFT屏显示任意内容三 1.概述 这篇文章介绍使用ILI9341驱动提供的函数控制TFT屏显示字符串、图形、符号等等内容的编辑和展示。 2.硬件 2.1.硬件列表 名称数量Arduino Uno12.8" TFT彩色液晶触摸屏模块(ILI9431)110K 电阻…

SpringBootWeb 篇-深入了解请求响应(服务端接收不同类型的请求参数的方式)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 请求响应概述 1.1 简单参数 1.2 实体参数 2.3 数组集合参数 2.4 日期参数 2.5 json 参数 2.6 路径参数 3.0 完整代码 1.0 请求响应概述 当客户端发送不同的请求参…

中国1KM年相对湿度数据集1981-2020

大气相对湿度(RH)是气象/气候监测和研究的关键因素。然而,相对湿度在气候变化研究中的应用并不是很普遍,部分原因是相对湿度观测系列容易由于观测系统中的非气候变化而产生不均匀偏差。 该数据集是中国1km分辨率年相对湿度数据&am…

【MsSQL】数据库基础 库的基本操作

目录 一,数据库基础 1,什么是数据库 2,主流的数据库 3,连接服务器 4,服务器,数据库,表关系 5,使用案例 二,库的操作 1,创建数据库 2,创建…

华为配置Ethernet over GRE实现AC与无线网关之间的二层互通

华为配置Ethernet over GRE实现AC与无线网关之间的二层互通 组网图形 图1 通过Ethernet over GRE实现AC与无线网关之间的二层互通的组网图 组网需求数据规划配置思路操作步骤配置文件 组网需求 如图1所示,某企业通过无线网络为用户提供上网服务,其中A…

探索静态住宅代理IP:网络安全的隐形守护者

在当今这个数字化高速发展的时代,网络安全问题愈发凸显其重要性。无论是企业级的网络运营,还是个人用户的网络活动,都需要一个安全、稳定的网络环境。而在这个环境中,静态住宅代理IP以其独特的优势,逐渐成为了网络安全…

Java——类与对象

目录 一、面向对象的初步认识 1.1 什么是面向对象 1.2 面向对象与面向过程 二、类的定义与使用 2.1 简单认识类 2.2 类的定义格式 三、类的实例化 3.1 什么是实例化 3.2 类和对象的说明 四、this引用 4.1 为什么要有this引用 4.2 什么是this引用 ​编辑 4.3 this引用…

鸿蒙OpenHarmony:【常见编译问题和解决方法】

常见问题 常见编译问题和解决方法 鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 提示“usr/sbin/ninja: invalid option -- w” 现象描述: 编译失败,提示“usr/sbin/ninja: invalid…

设备二维码怎么生成?三分钟即可搞定

在现代工业生产中,设备的维护和巡检是保障生产连续性和安全性的重要环节。随着技术的发展,二维码技术因其便捷性和高效性被广泛应用于设备巡检中。 给每个设备配备一个二维码,一线人员用手机扫一扫,几秒钟就能上报巡检结果&#…

Measurement and Analysis of Large-Scale Network File System Workloads——论文泛读

ATC 2008 Paper 分布式元数据论文阅读笔记整理 问题 网络文件系统在当今的数据存储中发挥着越来越重要的作用。使用网络文件系统可以降低管理成本,从多个位置可靠地访问的数据。这些系统的设计通常以对文件系统工作负载和用户行为的理解为指导[12,19&a…

docker 容器无法直接读取宿主机文件

最近一个需求, 要在后端直接使用代码直接生成 pdf 文档, 由于使用的 apache 的工具包, 该工具包无法直接解析中文字体, 需要导入外部 中文插件包, 相关代码如下: PDPage page new PDPage(PDRectangle.A4);document.addPage(page);PDFont fontFile PDType0Font.load(document…

瑞友天翼应用虚拟化系统SQL注入漏洞

文章目录 漏洞描述漏洞原理影响版本漏洞复现防御方法 漏洞描述 瑞友天翼应用虚拟化系统是基于服务器计算架构的应用虚拟化平台,它将用户各种应用软件集中部署到瑞友天翼服务集群,客户端通过 WEB 即可访问经服务器上授权的应用软件,实现集中应…

Python中的多进程、多线程、协程

Python中的多线程、多进程、协程 一、概述 1. 多线程Thread (threading): 优点:同一个进程中可以启动多个线程,充分利用IO时,cpu进行等待的时间缺点:相对于进程,多线程只能并发执…

深入理解JavaScript数组

深入理解JavaScript数组:玩转数据结构 前言数组的基础知识什么是数组如何创建一个数组如何访问数组元素 数组的常用操作数组的长度 length更改数组项数组的遍历数组类型的检测数组的添加和删除元素(头尾操作 push()、pop()、unshift()、shift()&#xff…

enable_shared_from_this使用笔记

解决了&#xff1a; 不能通过原指针增加引用次数的问题 &#xff0c;通过weak_ptr实现。 class MyCar:public std::enable_shared_from_this<MyCar> { public:~MyCar() { std::cout << "free ~Mycar()" << std::endl; } };int main() { MyCar* _…

centos7下fastdfs分布式部署

需要先在159及120服务器上安装fastdfs服务 可参考&#xff1a;centos7部署FastDFS服务_centos fastdfs 增加到服务中-CSDN博客 1、整体架构&#xff0c;使用3个服务器节点&#xff0c;其中两台为跟踪器节点及存储节点&#xff0c;一台服务器搭建nginx做统一入口进行负载均衡 …

K8S安装并搭建集群

1. 先给每台机器安装docker环境 卸载旧的docker yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 配置docker的yum库 yum install -y yum-utilsyum-config-manager --a…

JavaEE之线程(3)_线程的开始、中断、等待、休眠线程、线程的状态

前言 在本栏的上一节&#xff08;https://blog.csdn.net/2301_80653026/article/details/138500558&#xff09;&#xff0c;我们重点讲解了五种不同的创建线程的方式&#xff0c;我们还介绍了Tread类的常见构造方法和常见属性&#xff0c;在这一节中我们将会继续介绍Tread类。…

简单的Python HTML 输出

1、问题背景 一名初学者在尝试将 Python 脚本输出到网页上时遇到了一些问题。他当前使用 Python 和 HTML 进行开发&#xff0c;并且遇到了以下问题&#xff1a; 担心自己的代码过于复杂&#xff0c;尤其是 WebOutput() 函数。希望通过 JavaScript 使用 HTML 模板文件更新数据。…