C++当中的继承

news2024/11/20 8:38:36

  在C++当中继承是一个非常重要的语法。我们可以使用继承快速的进行代码的复用以及对代码进行扩展操作。首先我们来进行学习继承的基本语法。

  (一)继承的语法方式

  还记得我们之前学习的访问限定符吗?就是class里面的private,public,protected限定符。我们可以根据限定符的不同设置访问类当中数据的权限。public限制的区域我们可以通过对象在类外面就可以进行访问。protected限制的区域在类当中其实跟private限定的区域没有什么不同,都是可以在类里面进行访问,但是在类外面不能通过创建的对象进行访问。

  对于我们的继承同样需要用到这三个限定符:在继承当中这三种限定符可以表示继承的方式。其中public表示公开继承,protected表示保护继承,private表示私有继承。

  继承的限定符和类当中的限定符是共同作用于我们类当中的成员函数和成员变量的。比如:对于共有继承,对于我们类当中继承的使用权限就是最大的,继承之后我们基类当中的所有的原有元素的权限均保持不变。对于保护继承来说,对于基类当中的公有的成员函数和成员变量会缩小一下权限变为保护的私有变量,其余变量和函数权限保持不变。对于私有继承所展示的权限是最小的我们不能使用基类当中的任何内容,包括在类的内部也不行。

   但是需要我们注意的是:在继承这一部分来说,protected保护继承就会跟我们的private继承有很大程度上的区别。对于我们的保护继承来说我们可以在类的内部进行访问该部分的成员变量或者成员函数,但是我们不允许在类的外面访问该部分的成员函数(实质上就相当于我们之前的private限定之后的区域)。对于private继承来说我们不允许在任何位置进行访问,包括在类的内部也是。

(二)基类和派生类进行转换

  这一部分我们需要理解基类和派生类进行转换的过程,首先我们都知道指定的变量即使类型不同的时候我们的编译器也会进行适当的隐式类型转换操作。如果允许会自动将数据转换成为我们想要的数据。例如:

double d=1.1;
int i=d;   
//系统会自动进行强制类型转换操作,
//将double类型的数据转换成为int类型的数据

  对于我们的基类跟派生类也不例外,同样会自动进行转换,但是在转换的时候有很多隐形的要求。对于我们的派生类来说,在其中会包含我们基类当中的数据,同时可能会有新的数据出现。其结构就类似于下图所示:

  所以在进行转换的时候我们就需要进行注意了:我们只能使用派生类对基类进行赋值,但是不能使用基类对于我们的派生类进行赋值。其实很容易进行理解:在派生类当中我们会有一些新的数据产生,这个时候如果我们使用基类给派生类进行赋值的时候就会缺失这一部分的数据。但是如果我们使用派生类对于我们的基类进行赋值的时候不会缺失任何的数据,只需要进行数据的切片即可。编译器会自动找出跟基类相同的数据进行切片之后直接赋值。

  使用派生类给基类进行赋值:

  程序运行一切正常。

  使用基类给派生类进行赋值:

 系统产生报错,提示我们左操作数不匹配的问题。

 估计大家会想起一个很古老的问题:是不是没有加const的原因呢?我们来回顾一下什么时候在类型转换的时候需要加上const对类型进行修饰:

  当我们在数据转换的时候我们曾经有过一个概念,数据在隐式类型转换的时候我们会产生一个临时的中间变量,这个临时的中间变量具有常量的属性。所以如果我们想要进行引用的时候需要使用const修饰符进行修饰。不然就会产生报错。

  我们会发现我们使用const修饰之后报错消失了。那么我们回过头查看继承这部分出现的问题:

  我们会发现这一部分的报错并不涉及任何引用方面的内容,所以可以断定不是相同的错误原因。

  那么我们在使用派生类对基类进行赋值的时候,如果使用引用是否需要加上const才可以编译通过呢?

  我们通过实践验证的时候就会发现:我们其实并不需要使用const进行任何的修饰操作就可以正常的运行代码,这是因为我们的切片之后的操作只是一个单纯的复制操作,并不存在类型转换的问题,所以不需要产生临时的中间变量,也就不存在需要使用const修饰的问题。

  (三)继承当中的作用域

  对于基类当中的变量来说其作用域就是在基类当中,但是一旦被继承之后根据继承的方式不同我们同样可以在不同的地方进行不同的访问和修改。如果当我们使用引用或者指针指向派生类当中的基类的时候就会将我们的基类跟我们的派生类链接起来,形成一个统一的整体,在我们修改派生类当中的基类成员的时候同样会修改到我们基类当中原本存储的数据。例如:

  同样的道理我们修改a的时候也会修改到我们的派生类当中的基类当中的元素。其实很好理解,因为我们使用引用的时候仅仅是将数据切片出来之后,使用一个基类引用而已,数据还是我们派生类当中保存的数据。

  那么我们会很容易想到:要是在基类当中存在跟我们派生类当中的元素重复的成员类型呢?比如说同名的成员函数以及成员变量之类的。

  在语法当中我们将继承当中的同名的成员函数和成员变量叫做隐藏。对于构成隐藏的函数或者变量来说我们只能在特定的区域内访问特定的对象。例如:

  运行相应的程序之后我们会发现我们调用的是派生类当中的成员函数,并不是我们基类当中的成员函数,这个很好理解,编译器在调用函数的时候会自动进行就近检查。如果定义的类当中存在该函数的时候就不会到基类当中进行查找了,如果没有的话就会进入基类当中进行相应的查找操作。那么问题来了:我们要怎样才可以调用基类当中被隐藏的成员函数呢?这个时候我们就需要使用域作用访问限定符进行访问了。这样我们的编译器就会直接进入我们指定的类当中进行查找。测试如下:

  (四)派生类当中的默认成员函数

  记得我们在学习类的时候有一部分会学到默认成员函数的概念,默认的成员函数大致分为以下几种:第一种为默认构造函数,也就是在不手动添加构造函数的时候默认生成的构造函数,还有拷贝构造函数,当我们不手动编写的时候系统同样会默认生成一个拷贝构造。赋值运算符重载,以及析构函数,这几种函数当我们不主动设置的时候都会自动进行生成。

  那么对于我们的派生类默认成员函数有什么要求呢?对于我们的派生类来说其中实质上是由两部分组成的,第一类是我们通过继承得到的基类的部分,另一部分是我们派生类自己专属的那一部分。当我们在调用派生类对象的时候,系统为了保证我们派生类当中基类部分的数据完整性会自动调用基类当中的构造函数,对基类当中的数据进行初始化操作。之后我们在通过我们派生类的构造函数对我们的派生类再进行初始化,最终得到我们的结果。例如:

  当我们在创建B对象的时候系统会自动调用A的构造函数对A进行初始化操作,如果我们没有指定调用A的构造函数的话,系统就会自动调用默认的构造函数。但是需要我们注意的是:是否真的存在默认的构造函数。所谓的默认的构造函数实质上也就是系统自动生成的构造函数,但是我们不能自己编写构造函数,否则系统默认生成的构造函数就会失效。还有就是我们自己编写的无参的构造函数,最后就是全缺省的构造函数。

  当我们不存在默认的构造函数,同时没有进行指定调用特定的构造函数的时候系统就会产生报错:

  实质上并不是一定要拥有无参的构造函数,我们也可以指定调用已经存在的构造函数。

  当我们明确指出我们需要调用的构造函数的时候即使没有默认的构造函数程序也可以正常的运行。对于我们的其他的默认成员函数也是相同的。

  但是我们需要注意的是构造函数调用的顺序,首先我们的编译器会自动调用基类对象的构造函数,之后才会调用我们派生类的构造函数进行初始化,这是因为我们在派生类的构造函数当中可能会对基类当中的成员变量以及成员函数进行调用,先调用基类的构造函数就可以避免未知错误的产生。

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

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

相关文章

直播间没有自然流,如何突破?

如果你的直播间完全没有自然流量,不用担心,有四种方法可以解决这个问题。 第一种方法是延长直播时长。如今的账号系统与以前不同,现在自然流量非常珍贵。以前,新账号即使没有数据,平台也会给一些流量,但现在…

校园管理新篇章:Spring Boot系统实现策略

第3章 系统分析 3.1 需求分析 校园管理系统主要是为了提高用户的工作效率和更方便快捷的满足用户,更好存储所有数据信息及快速方便的检索功能,对系统的各个模块是通过许多今天的发达系统做出合理的分析来确定考虑用户的可操作性,遵循开发的系…

jmeter设置全局token

1、创建setup线程,获取token的接口在所有线程中优先执行,确保后续线程可以拿到token 2、添加配置原件-Http信息头管理器,添加取样器-http请求 配置好接口路径,端口,前端传参数据,调试一下,保证获…

2024社群空间站全自动付费进群系统九块九进群源码

多种玩法:付费VIP玩法、同城行业群裂变玩法、全民K歌群裂变玩法、拼多多群玩法、VIP领取百度网盘资料玩法、单群付费玩法;

WTL580-电子锁微波雷达应用解决方案,5.8GHz精准人体感知,触发高效交互新体验

一、简介 随着智能电子门锁普及,电子门锁的市场也随着打开,安装智能化电子门锁也为大势所趋。现我司推出基于WTL580微波雷达的电子锁应用方案,通过检测门锁周围是有活动人体存在来激活门锁。我司WTL580微波雷达方案采用5.8GHz微米波雷达传感器…

mac系统安装最新(截止2024.9.13)Oracle JDK操作记录

文章目录 下载JDK22配置环境变量验证环境变量是否生效整体命令如下 下载JDK22 打开最新版Oracle JDK下载地址 选择想要安装的JDK版本,然后选择适合兼容Mac机器的版本(Intel/arm),建议直接下载安装程序,可视化安装 默…

栈的定义和基本操作的实现

写代码:定义顺序存储的栈(数组实现),数据元素是 int 型 写代码:基于上述定义,实现“出栈、入栈、判空、判满”四个基本操作 写代码:定义链式存储的栈(单链表实现) 写代…

零钱兑换二维dp实现(力扣--动态规划)

文章目录 1.题目描述2.解题思路3.代码实现 1.题目描述 题目链接:零钱兑换 2.解题思路 1.确定二维dp[i][j]的含义: dp[i][j] 前i个物品任取,装入容量为j的背包种,最少的硬币个数是dp[i][j] 2.确定递推公式: dp[i][j]…

【日语学习必备】5款超准实时翻译软件,让你的网课不再有障碍!

日语水平不过关,没办法实时听懂日语会议或日语网课内容怎么办? 两种方法! 一、利用日语实时翻译软件,也就是所谓同声传译的方式实时将日语转换为中文 二、先将会议或网课等内容录制下来,再借助语音或视频翻译软件&am…

利士策分享,探索无界:心灵之旅,发现未知精彩

利士策分享,探索无界:心灵之旅,发现未知精彩 梦想的种子,在心田生根发芽 正如每一颗种子都蕴含着生命的奥秘,每个人心中那颗探索的种子,也藏着对未知世界的渴望与追求。它告诉我们,成长不仅仅…

Unite Shanghai 2024 技术专场 | Unity 6及未来规划:Unity引擎和服务路线图

在 2024 年 7 月 24 日的 Unite Shanghai 2024 技术专场演讲中,Unity 高级技术产品经理 Jeff Riesenmy 带来演讲 Unity 6 and Beyond: A Roadmap of Unity Engine and Services。作为本次 Unite 首场专题演讲,他介绍了 Unity 引擎的最新进展及其配套的工…

猫头虎分享:15种数码苹果16抢购攻略

猫头虎分享:15种数码苹果16抢购攻略 大家好,我是猫头虎!今晚8点,就是大家期待已久的苹果16抢购时刻,你准备好了吗?为了帮助大家顺利抢到心仪的机型,我精心准备了15种抢购指南,总有一…

[C#学习笔记]LINQ

视频地址:LINQ入门示例及新手常犯的错误_哔哩哔哩_bilibili 强烈推荐学习C#和WPF的朋友关注此UP,知识点巨多,讲解透彻! 一、基本概念 语言集成查询(Language-Intergrated Query) 常见用途 .Net原生集合(List,Arra…

“勇者斗恶龙”即将上演,乐道L60剑指Model Y

文/王俣祺 导语:只要说到“二十多万”“大品牌”“纯电SUV”这一系列关键词,特斯拉Model Y一定是绕不开的车型,从近几年的销量来看,目前市面上很难有车型能“硬刚”。不过既然有“恶龙”就会有“勇者”,蔚来子品牌乐道…

“薅羊毛”时间到, 容声以旧换新“钜惠”升级

9月13日,由佛山市商务局、顺德区人民政府指导,海信家电集团主办的以旧换新佛山发布活动启幕。 海信家电(SZ 000921,HK 00921)旗下容声冰箱叠加国家以旧换新补贴,把“以旧换新”升级到“品质换新”&#xf…

汤臣倍健业绩大幅下滑:经销商减少131家,销售费用转化不达预期

《港湾商业观察》廖紫雯 在膳食营养补充剂(VDS)行业竞争加剧的情况下,日前,汤臣倍健股份有限公司(以下简称:汤臣倍健,300146.SZ)披露2024年半年报业绩情况。上半年,公司…

爱普生相机SD卡格式化后数据恢复指南

我借了朋友的‌爱普生相机,想查看一下内存,哎呀,一不小心按错了,竟然执行了格式化操作,这可真是太让人郁闷了,这还有机会挽救数据吗?心塞,求帮助! 随着数码摄影的普及&am…

GUI编程10:窗口监听事件

视频链接:12、窗口监听事件_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p12&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.使用成员内部类方式实现窗口监听 ackage com.yundait.lesson03;import java.awt.*; import java.awt.event.Win…

学习之git的团队协作

git团队协作 一 团队内协作 生成SSH公钥私钥 一(跨团队协作)

java的ReentrantLock原理

示例代码如下,主要包括两个方法: public static void main(String[] args) throws InterruptedException {Lock lock new ReentrantLock();lock.lock();lock.unlock();}双向链表初始状态: 双向链表从尾节点添加阻塞的节点: 读源…