当前位置: 首页 > news >正文

C++相关概念和易错语法(19)(继承规则、继承下的构造和析构、函数隐藏)

1.继承规则

继承的本质是复用,是结构上的继承而不是内容上的继承,近似于在子类中声明了父类的成员变量。

(1)写法:class student : public person
     派生类(子类),继承方式,基类(父类) 

它们都分public、protected、private三种,但是含义并不相同。

(2)区分访问限定符和继承方式

访问限定符修饰的是在当前类里面是否可以访问,而继承方式是指在继承的类里面的访问方式,并且一个成员继承后的访问限定符是父类的访问限制符和子类继承方式两者间的较小权限如果A有public成员a,而以protectd继承,因此子类成员的访问限制符是protected。

访问权限由大到小是public>protected>private,protected和private在继承语法外没有区别。比如protected成员public继承后是protected,protected成员private继承后是private,public成员public继承后是public,这都非常容易理解。


#include <iostream>
using namespace std;class A
{
public:int _a = 0;
protected:int _b = 1;
private:int _c = 2;
};class B : public A
{
public:void GetNum(){cout << _a << " " << _b  << " " << _d << endl;}int _d = 3;
};int main()
{B().GetNum();return 0;
}

但是要注意private成员无论以何种方式继承,不管是public、protected还是private继承,最终子类成员的访问权限都是private且这个private成员不能被子类使用(包括访问,修改等)

看起来这个成员没有被继承,但实际上子类包含该成员。我们可以从监视窗口和类的大小双重验证这个结论。

(3)在继承里还规定友元关系不能继承,父类的友元不是子类的友元,只有子类自己声明友元

(4)形象理解:父的成员是protected意味着这些成员对外是个秘密,但在自己家庭中不算个秘密,但家庭中的每个人都有义务对外保守这个秘密,即protected无论以何种方式继承对外都不可见。

如果父成员有个private意味着这个成员是自己的秘密,不能给任何人说,比如家里有个隐藏的地下室。但是在继承给自己孩子这个房子时,孩子不知有这个地下室,但这个地下室真实存在,即private无论以何种方式继承对子对外均不可见,但这个private成员真实存在。

父的朋友不是子的朋友,即友元关系不能继承。

(5)protected和private区分

protected在继承以后才有意义。protected和private对外的功能都一样,都是不可见,它们区别在protected对整个继承体系开放(前提没有子类以private继承它),而private是只有该类能访问,其子类也不能访问。

当中途被继承为private后,对子该成员依然不可见。

(6)默认继承方式

我们也可以选择不写继承方式,这个时候class默认私有继承,struct默认以public继承,注意这和默认访问限定符一样,但这是两个概念。

2.继承的函数调用

我们先尝试解读下面的代码,这能帮助我们初步理解继承函数调用的特征:


#include <iostream>
using namespace std;class A
{
public:A(int a, int b, int c):_a(a),_b(b),_c(c){}void GetNum(){printf("%d %d %d\n", _a, _b, _c);}int _a = 0;
protected:int _b = 1;
private:int _c = 2;
};class B : public A
{
public:B():A(7, 8, 9), _d(5){}void GetNum(){printf("%d\n", _d);}int _d = 3;
};int main()
{B().A::GetNum();B().GetNum();return 0;
}

结果是

(1)构造函数

A作为父类它的构造函数正常写就是了,我们重点关注B的构造函数。

我们知道,构造函数实际构造的顺序是声明的顺序而非初始化列表的顺序。这里我们可以理解为B子类的第一个成员声明是匿名的A,在初始化时要根据A的构造函数把A当作一个整体用匿名初始化对象的方式A(7,8,9)来处理,不能直接对A的成员变量直接初始化继承的A对象和创建一个A对象一样都不会复制函数和static变量,在需要时都是直接去A里面取,即整个继承体系共享一套函数和static变量

(2)函数的隐藏

在继承体系中是允许出现同名函数的,但是这并不构成函数重载,因为函数重载的前提是必须在同一个作用域定义两个同名函数,而这里很明显是在两个类域里定义的同名函数,所以一定不构成重载,而是构成函数的隐藏(只需要同名就构成隐藏了,要和后面的多态区分开)。

如果构成了函数隐藏的话,应该怎么区分调用这两个函数呢?很多人会以为能像函数重载的调用那样根据参数匹配程度来调用,但这个逻辑在继承里走不通,万一我就想利用隐式类型转换调用子的成员函数,但是参数却匹配了父的成员函数呢?万一是我参数写错了导致匹配错误的情况呢?这些问题都会导致歧义的发生。所以规定,只要构成函数隐藏,调用父类一定要指明类域,调用当前类的不用指明,如果不指明类域,一律只按调用当前类的函数来处理,就算此时调用匹配父类的函数参数。

我们这里还可以学到,虽然我们不能直接访问父类的私有成员_c == 9,但是我们可以选择调用父类的非private和protected函数,从而达到间接访问的目的。

(3)析构函数与构造函数

析构函数的理解相对复杂,我们先看一下下面的代码,这能帮助我们深入理解构造和析构函数:


#include <iostream>
using namespace std;class A
{
public:~A(){delete _a;}int* _a = new int(1);
};class B : public A
{
public:B():_b(_a){}~B(){A::~A();*_b = 2;}int* _b;
};int main()
{B a;return 0;
}

结果是报错,接下来我会详细分析里面的代码

为什么写作A::~A();

析构函数的名字会被统一处理为destructor(),父子类的析构函数同名构成了函数隐藏,因此想要调用父的析构函数,就必须要指定类域,这个底层细节需要我们记住。这个特殊处理的原因在多态我会提及。

为什么报错?

由于在父类的析构函数调用后间接使用了父类的成员,所以出现越界访问的情况。

我们还能发现B的构造函数借助了A的成员变量。这里要区分开的是,在子类初始化父类时只能以父类为整体去调用它的构造函数如A(7,8,9),而本质上继承的只是它的成员变量,在子类的构造函数中可以直接用父类的成员。

如此一来,我们能发现,子类的构造函数可能会依靠父类的成员变量,若父类先析构,那在子类需要用到父类成员变量时就可能会发生越界访问。所以规定,父类的构造函数一定先于子类,父类的析构一定晚于子类(构造先父后子,析构先子后父)。

在实现层面上,由于子类的第一个成员变量默认是父类A,所以我们可以不用关心,毕竟初始化顺序是按声明而不是初始化列表。但是我们要避免显式地调用父类的析构,即A::~A()不要出现在我们的继承代码中。当子类的析构函数走完后,会去自动调用父类的析构。同理,如果没有显式写构造,编译器也会首先自动调用父类的默认构造。

相关文章:

C++相关概念和易错语法(19)(继承规则、继承下的构造和析构、函数隐藏)

1.继承规则 继承的本质是复用&#xff0c;是结构上的继承而不是内容上的继承&#xff0c;近似于在子类中声明了父类的成员变量。 &#xff08;1&#xff09;写法&#xff1a;class student : public person 派生类&#xff08;子类&#xff09;&#xff0c;继承方式&…...

使用GPT-4和ChatGPT构建应用项目

文章目录 项目1:构建新闻稿生成器项目2:YouTube视频摘要项目3:打造《塞尔达传说:旷野之息》专家项目4:语音控制项目1:构建新闻稿生成器 GPT-4和ChatGPT等LLM专用于生成文本。我们可以使用GPT-4和ChatGPT在各种场景中生成文本,举例如下。 电子邮件合同或正式文档创意写作…...

mobx学习笔记

mobx介绍 mobx是一个功能强大&#xff0c;上手容易的状态管理工具。MobX背后的哲学很简单:任何源自应用状态的东西都应该自动地获得。利用getter和setter来收集组件的数据依赖关系&#xff0c;从而在数据发生变化的时候精确知道哪些组件需要重绘。 mobx和redux的区别 mobx更…...

深入理解 Cowboy WebSocket:使用 Erlang/OTP 构建高效的即时通讯(IM)应用

深入理解 Cowboy WebSocket&#xff1a;使用 Erlang/OTP 构建高效的即时通讯(IM)应用 引言 实时通信技术在现代 Web 应用中扮演着核心角色&#xff0c;而 WebSocket 作为其中的关键技术&#xff0c;已成为即时通讯(IM)系统不可或缺的一部分。Cowboy&#xff0c;这个基于 Erla…...

算法的几种常见形式

算法&#xff08;Algorithm&#xff09; 算法&#xff08;Algorithm&#xff09;是指解决问题或完成任务的一系列明确的步骤或规则。在计算机科学中&#xff0c;算法是程序的核心部分&#xff0c;它定义了如何执行特定的任务或解决特定的问题。算法可以用多种方式来表示和实现…...

SpringBoot新手快速入门系列教程二:MySql5.7.44的免安装版本下载和配置,以及简单的Mysql生存指令指南。

我的教程都是亲自测试可行才发布的&#xff0c;如果有任何问题欢迎留言或者来群里我每天都会解答。 我们要如何选择MySql 目前主流的Mysql有5.0、8.0、9.0 主要区别 MySQL 5.0 发布年份&#xff1a;2005年特性&#xff1a; 基础事务支持存储过程、触发器、视图基础存储引擎…...

Elasticsearch 更新指定字段

Elasticsearch 更新指定字段 准备条件查询数据更新指定字段更新子级字段 准备条件 以下查询操作都基于索引crm_clue来操作&#xff0c;索引已经建过了&#xff0c;本文主要讲Elasticsearch更新指定字段语句&#xff0c;下面开始写更新语句执行更新啦&#xff01; 查询数据 查…...

Koa.js、Egg.js与Express.js:探析三大Node.js框架的异同

在Node.js的世界里&#xff0c;选择合适的框架对于构建高效、可维护的后端服务至关重要。Express.js、Koa.js 和 Egg.js 是三个备受欢迎的框架&#xff0c;它们各有特色&#xff0c;适用于不同的开发场景。本文旨在深入探讨这三个框架的区别&#xff0c;并通过代码示例帮助开发…...

【MYSQL】如何解决 bin log 与 redo log 的一致性问题

该问题问的其实就是redo log 的两阶段提交 为什么说redo log 具有崩溃恢复的能力 MySQL Server 层拥有的 bin log 只能用于归档&#xff0c;不足以实现崩溃恢复&#xff08;crash-safe&#xff09;&#xff0c;需要借助 InnoDB 引擎的 redo log 才能拥有崩溃恢复的能力。所谓崩…...

翻译语音识别在线的软件,分享4款实用的软件!

在全球化日益加速的今天&#xff0c;语言沟通已成为人们生活中不可或缺的一部分。无论是商务洽谈、学术交流还是日常交流&#xff0c;翻译语音识别技术都扮演着举足轻重的角色。今天&#xff0c;我们就来揭秘一下&#xff0c;那些能让你在语言沟通中如虎添翼的翻译语音识别软件…...

Qt 的Q_PROPERTY关键字

Qt 的Q_PROPERTY关键字 1. Q_PROPERTY 的由来2. 实现原理3. Q_PROPERTY 的特点4. Q_PROPERTY 的属性5. 应用说明示例代码示例代码连接信号和槽的多种方式处理信号和槽的注意事项 QT的元对象系统1. 元对象系统的由来2. 实现原理3. 元对象系统的特点4. 元对象系统的属性5. 应用说…...

github 下载提速的几种方法

1. 代理下载&#xff08;无需注册&#xff09; //toolwa.com/github/ //d.serctl.com/2. 转入 Gitee 加速 将项目镜像到 Gitee 中下载加速 3. 使用 Watt Toolkit 加速 Watt Toolkit //steampp.net/选择合适的版本下载 选择 github&#xff0c;一键加速 4.CDN 加速 (修改…...

【Oracle】实验三 Oracle数据库的创建和管理

【实验目的】 掌握Oracle数据库的创建方法使用DBCA创建数据库在数据库中装入SCOTT用户及其表 【实验内容】 使用DBCA创建数据库&#xff0c;名为MYDB&#xff0c;找到其初始化文件(文本型和服务器型文件都要找到)&#xff0c;查看各类默认位置并记录下来(包括物理文件所在目…...

Linux rpm和ssh损坏修复

背景介绍 我遇到的问题可能和你的不一样。但是如果遇到错误一样也可以按此方案尝试修复。 我是想在Linux上安装Oracle&#xff0c;因为必须在离线环境下安装。就在网上搜一篇文章linux离线安装oracle&#xff0c;然后安装教程走&#xff0c;进行到安装oracle依赖包的时候执行了…...

仕考网:公务员考试面试时间一般多长?

公务员考试主要分为笔试与面试两个阶段&#xff0c;其中面试是笔试通过的下一关&#xff0c;面试的具体安排通常由相关考试机构或招录单位负责发布并通知考生。 公务员面试的持续时间一般在30分钟至1小时之间&#xff0c;具体时长可能因地区和招录单位的不同而有所变化。常见的…...

C语言作业5(学生管理系统C语言)

成学生管理系统 1> 使用菜单完成 2> 有学生的信息录入功能&#xff1a;输入学生个数&#xff0c;并将学生的姓名、分数录入 3> 查看学生信息&#xff1a;输出所有学生姓名以及对应的分数 4> 求出学习最好的学生信息&#xff1a;求最大值 5> 按姓名将所有学…...

OS Copilot:新手测评体验

文章目录 前言一、OS Copilot&#xff08;阿里云操作系统智能助手&#xff09;简介二、测评体验总结OS Copilot 产品体验评测OS Copilot 产品功能反馈 前言 本文简单分享一下自己使用OS Copilot测评体验。 一、OS Copilot&#xff08;阿里云操作系统智能助手&#xff09;简介 …...

PS 2024【最新】中文白嫖版!,安装教程,图文步骤

文章目录 软件介绍软件下载安装步骤 软件介绍 Photoshop&#xff0c;简称“PS” Adobe Photoshop&#xff0c;简称“PS”&#xff0c;是由Adobe Systems开发和发行的图像处理软件。Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具&#xff0c;可以有效地…...

bind方法的使用

在JavaScript或TypeScript中&#xff0c;this.data.setEventListener(this.onAddEvent.bind(this)); 和 this.data.setEventListener(this.onAddEvent); 之间的主要区别在于this关键字的绑定方式。 不使用.bind(this) 当你直接传递函数引用 this.onAddEvent给 setEventListene…...

MySQL数据库基本操作-DDL和DML

1. DDL解释 DDL(Data Definition Language)&#xff0c;数据定义语言&#xff0c;该语言部分包括以下内容&#xff1a; 对数据库的常用操作对表结构的常用操作修改表结构 2. 对数据库的常用操作 功能SQL查看所有的数据库show databases&#xff1b;查看有印象的数据库show d…...

iOS 应用内存超过多少会收到系统内存警告 ?

iOS 应用内存超过多少会收到系统内存警告 &#xff1f; 在 iOS 应用中&#xff0c;系统内存警告的触发是由 iOS 操作系统动态决定的&#xff0c;并不是一个固定的阈值。系统会根据当前设备的可用内存、正在运行的其他应用程序的内存需求以及当前应用程序的内存占用情况来判断是…...

【分布式系统】Filebeat+Kafka+ELK 的服务部署

目录 一.实验准备 二.配置部署 Filebeat 三.配置Logstash 四.验证 一.实验准备 结合之前的博客中的实验 主机名ip地址主要软件es01192.168.80.101ElasticSearches02192.168.80.102ElasticSearches03192.168.80.103ElasticSearch、Kibananginx01192.168.80.104nginx、Logs…...

Qt Qwt 图表库详解及使用

文章目录 Qt Qwt 图表库详解及使用一、Qwt 概述二、安装 Qwt1. 下载和编译 Qwt2. 在项目中使用 Qwt三、Qwt 的基本使用1. 创建一个简单的折线图2. 添加图例和自定义样式四、Qwt 的交互功能1. 启用缩放和平移2. 启用数据点选择五、Qwt 的高级特性1. 实时数据更新2. 多轴绘图六、…...

基于B站视频评论的文本分析,采用包括文本聚类分析、LDA主题分析、网络语义分析

研究主题 本研究旨在通过对B站视频评论数据进行文本分析&#xff0c;揭示用户评论的主题、情感倾向和语义结构&#xff0c;助力商业决策。主要技术手段包括Python爬虫、LDA主题分析、聚类分析和语义网络分析。首先&#xff0c;利用Python爬虫采集大量评论数据并进行预处理。运…...

【Qt】xml Dom复制

1. 功能 将A.xml文件中的copyNode节点全部复制到B.xml中的testRoot节点。 2. 代码 #include <QDomDocument> #include <QFile> #include <QIODevice> #include <QtXml>void copyNodeXml() {// 源文件DOMQDomDocument ADoc;// 加载源文件QFile fileA(…...

MySQL联合索引最左匹配原则

MySQL中的联合索引(也叫组合索引)遵循最左匹配原则&#xff0c;即在创建联合索引时&#xff0c;查询条件必须从索引的最左边开始&#xff0c;否则索引不会被使用。在联合索引的情况下&#xff0c;数据是按照索引第一列排序&#xff0c;第一列数据相同时才会按照第二列排序。 例…...

2024最新最全面的软件测试自动化面试题(含答案)

1.如何把自动化测试在公司中实施并推广起来的&#xff1f; 选择长期的有稳定模块的项目 项目组调研选择自动化工具并开会演示demo案例&#xff0c;我们主要是演示selenium和robot framework两种。 搭建自动化测试框架&#xff0c;在项目中逐步开展自动化。 把该项目的自动化…...

Linux磁盘-MBRGPT

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux磁盘涉及到的命令不是很多&#xff0c;但是在实际运维中的作用却很大&#xff0c;因为Linux系统及业务都会承载到硬盘上…...

kind kubernetes(k8s虚拟环境)使用本地docker的镜像

kubernetes中&#xff0c;虽然下载镜像使用docker&#xff0c;但是存储在docker image里的镜像是不能被k8s直接使用的&#xff0c;但是kind不同&#xff0c;可以使用下面的方法&#xff0c;让kind kubernetes环境使用docker image里的镜像。 kind – Quick Start 例如&#x…...

kafka发送消息流程

配置props.put(ProducerConfig.PARTITIONER_CLASS_CONFIG, RoundRobinPartitioner.class); public Map<String,Object> producerConfigs(){Map<String,Object> props new HashMap<>();props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,bootstrapServers…...

建设网站 系统占用空间/百度关键词优化多少钱

一&#xff0c;选用SLF4j和logback &#xff08;注&#xff1a;spring框架默认使用的事JCL日志框架&#xff09; 二&#xff0c;使用 1&#xff0c;如何在系统中使用slf4j&#xff08;不同于log4j&#xff09; 以后开发的时候&#xff0c;日志记录方法的调用&#xff0c;不…...

无锡本地网站有哪些/惠州seo外包平台

我在垂直链中有两个视图(viewA,viewB). viewA的宽高比应始终为1&#xff1a;1,而viewB的高度是动态的(可能为400dp,可能为700dp)预期成绩&#xff1a;当viewB的高度太大而无法容纳屏幕中的两个视图时,应减小viewA的宽度(保持宽高比).实际结果&#xff1a;如果viewB的高度太大,则…...

学做网站需要什么条件/怎么才能在百度上做引流呢

声音断续问题: 切换最下面 stereo就行...

试剂产品商城网站建设/seo知名公司

在Python中添加了装饰器&#xff0c;以使函数和方法包装(接收函数并返回增强函数的函数)更易于阅读和理解。最初的用例是能够在定义的顶部将方法定义为类方法或静态方法。没有装饰器语法&#xff0c;将需要一个相当稀疏且重复的定义&#xff1a;classWithoutDecorators:defsome…...

系统没有安装wordpress/郑州seo线上推广系统

input是三维的情况&#xff0c;size&#xff1a;W1H1D1此时&#xff0c;每个filter需要FFD1个权重值&#xff0c;总共K个filter&#xff0c;需要FFD1*K权重值。和一维一样&#xff0c;整个滑动过程中filter W0和W1值保持不变&#xff0c;可称作权值共享。 作者&#xff1a;7co…...

wordpress主题W3C/口碑营销案例ppt

ReplicatorG是一款简单易用的3d打印机控制软件&#xff0c;软件旨在帮助用户向其RepRap或CNC机器发出命令。该程序支持大多数常见的3D打印机&#xff0c;并且可以通过内置功能上传新固件。其还具有估计时间、模拟打印、生成代码、打印、暂停、停止、GCode生成器、编辑分层配置、…...