【C++】继承/虚拟继承/菱形虚拟继承

news2024/11/18 1:43:19

继承

  • 继承的概念
  • 继承体系中对象赋值转换
  • 继承方式对继承后的访问限定(重定义-同名隐藏)
  • 继承体系中派生类的默认成员函数
  • 友元函数、静态成员在继承中的特点
  • 菱形继承和菱形虚拟继承

继承的概念

为了让代码可以复用,当前类可以继承其他类的成员变量以及成员函数,这样就能使得当前类更加复杂,足以描述更加复杂的情况,当前增加新功能的类,我们称之为派生类,也叫子类,继承自哪个类,哪个类就是基类,也叫父类。这样的话,继承了父类的成员,子类中就有了父类所有的成员,同时还有自己新增加的成员。

class A
{
public:
	int _a;
};
class B : public A
{
public:
	int _b;
};

从代码中就能看到,B类继承了A类,并且是以public的方式继承的。这样B类中不仅包含了父类A的变量,也有自己新增的变量。(注意:针对不同的继承方式,继承后对父类的访问权限是不同的)

下面的表就展示了当使用不同继承方式时,子类访问父类成员的权限有什么区别

类成员/继承方式public继承protected继承private继承
基类的public成员publicprotectedprivate
基类的protected成员protectedprotectedprivate
基类的private成员private(子类不可见)private(子类不可见)private(子类不可见)

这个表为了更好记忆,可以这样去理解:
首先将可见性划分等级public>protected>private
要知道当前继承方式继承之后,子类对父类成员的访问权限,我们需要先看当前是什么方式继承的
继承方式为A,基类中成员权限等级如果存在比A等级高的,就会降级为当前等级。如果比A等级低的,则不进行权限的降级。

举例:
继承方式为protected,基类中fun1的访问权限为public,fun2访问权限为protected,fun3访问权限为private,那么子类中的继承下来的fun1的权限就被降级为protected,fun2的访问权限不变,fun3的访问权限不变。

注意:对于一个类中成员,使用class定义,如果没有指明访问权限,那么默认是private权限。使用struct定义,没有指明访问权限,默认是public权限。

继承体系中对象赋值转换

派生类对象是可以给基类对象赋值的,反之则不行
在这里插入图片描述
例如图中学生类给person类进行赋值是可以的,因为学生类中本来就包含了两部分变量,基类继承和子类新增。
而基类继承下来的可以顺理成章的赋值给基类,子类继承的不进行赋值即可。

为什么子类对象可以给基类对象赋值,而基类对象不能给子类对象赋值
但是如果反过来,让基类对象给子类对象赋值时,基类对象的变量赋值给了子类中继承自基类的,但是子类中子类新增就无法进行赋值了。

继承方式对继承后的访问限定(重定义-同名隐藏)

由于继承体系中基类和派生类都有独立的作用域,当子类和父类中有同名成员时,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)。
如果是成员函数的隐藏,只需要成员函数名一样即可。

继承体系中派生类的默认成员函数

6个默认成员函数,“默认”的意思就是指我们不写,编译器会变我们自动生成一个,那么在派生类中,这几个成员函数是如何生成的呢?

构造函数:
对于基类来说,如果基类没有显式定义构造函数,那么在子类的构造函数的初始化列表中是否调用基类的构造函数都可以。
如果基类显示定义构造函数了,那么在子类的构造函数的初始化列表中一定要调用基类的构造函数。

拷贝构造函数:
子类的拷贝构造函数中,一定要显式调用基类的拷贝构造函数,以完成基类部分的拷贝初始化。

赋值运算符重载:
子类的赋值运算符重载,一定要显式调用基类的赋值运算符重载,以完成基类部分的赋值。

析构函数:
子类的析构函数中,先调用子类的析构函数,子类的析构函数最后一句会自动添加基类的析构函数,用于调用基类的析构函数清理基类成员,这样就保证先清理子类对象成员再清理基类对象成员。

派生类对象的初始化是先调用派生类对象的构造函数,销毁派生类对象是先调用派生类对象的析构函数。

友元函数、静态成员在继承中的特点

一句话:友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员
基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例 。

菱形继承和菱形虚拟继承

首先我们要知道什么是单继承,什么是多继承:

单继承:一个子类只有一个直接父类时称这个继承关系为单继承
多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承
菱形继承:菱形继承是多继承的一种特殊情况。

在这里插入图片描述
如图即为菱形继承,其中BC类继承A类,D类继承BC类。
这样的继承方式会存在一个问题,数据冗余和二义性。

由于B和C都继承了一份A类的成员,那么D将B和C继承过来的时候会存在两份A类中的成员。这样的话,数据就被保存了两份,而且当需要通过D类对象访问A类成员时,就出现问题了,由于有两份A类的成员,那么到底是访问哪个类中的成员呢?
我们可以通过指定作用域来解决访问二义性的问题,但是无法解决数据冗余的问题。
因此就出现了菱形虚拟继承

什么是菱形虚拟继承?
专门用于解决由于菱形继承导致的数据冗余和访问二义性的问题。
我们直接来看普通的菱形继承和菱形虚拟继承之间,对象成员模型的区别。

//普通继承
class A
{
public:
	int _a;
};
class B : public A
{
public:
	int _b;
};
class C : public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};
//菱形虚拟继承
class A
{
public:
	int _a;
};
class B : virtual public A
{
public:
	int _b;
};
class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};

上述代码展示了两种继承方式的写法,下面我们来看下这两种继承方式对成员对象模型有什么区别
在这里插入图片描述

可以看到,普通继承方式中,就是按照继承顺序进行继承,存在多个_a。
在这里插入图片描述

可以看到,在虚拟继承中,对象模型发生了变化,基类A被置于最下方,而其余的B类C类和子类的相对顺序没有变化,但是B类C类中除了自己新增的成员,还多了一个ptr指针,我们称这个指针为虚基表指针。

这个虚基表指针指向的是一个虚基表。
而虚基表是这样的结构
在这里插入图片描述
虚基表通过查看子类对象相对于基类部分的偏移量后,就能够准确的找到基类部分,从而去修改基类部分的成员。
例如上述的继承体系中,

ptr1指向的内容中是这样的值
在这里插入图片描述
ptr1指向的内容中是这样的值
在这里插入图片描述

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

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

相关文章

阿里云OSS存储空间绑定自定义域名,浏览器通过自定义域名预览文件

阿里云官方文档: 如何绑定自定义域名_对象存储-阿里云帮助中心 华东1(杭州)地域创建了名为monkey的存储空间 Bucket:monkey Endpoint:oss-cn-hangzhou.aliyuncs.com 上传文件默认域名的url: https://monkey.oss-cn-han…

微信小程序nodejs+vue课程推荐报名学习分享平台uniapp

本文以实际运用为开发背景,运用软件工程原理和开发方法, 整个开发过程首先对课程分享平台进行需求分析,得出课程分享平台主要功能。接着对课程分享平台 进行总体设计和详细设计。总体设计主要包括小程序功能设计、小程序总体结构设计、小程序…

Python数据可视化小结

1. 引言 原始形式的数据对大多数人来说可能都是枯燥乏味的,但是如果掌握正确的可视化工具,给人的印象就会变得引人入胜。本文通过实际例子,让我们利用数据可视化工具来探索不一样的数据体验。 闲话少说,我们直接开始吧&#xff…

推荐3款超好用的海报设计软件!

在现代社会,海报设计已经成为了一种非常重要的视觉传达方式。如果你需要制作一个引人注目的海报,但却没有设计师的技能和经验,那么在线海报设计图片软件就是你的最佳选择。下面我们将介绍 5 款最受欢迎的在线海报设计图片软件,它们…

qt中使用QGIS实现二次开发导入shp格式地图(MSVC2019_64bit+qt5.15+qgis)

在qt开发过程中可能要导入自定义格式的图层地图,那么可以把这些数据导入qgis然后导出为shp格式文件,然后下载qgis源码,在qt项目中配置环境变量导入qgis有关的头文件,然后再引入shp数据格式的地图。 qgis处理数据 QGIS安装 QGIS…

oracle数据库当中用户的创建,添加,授权,以及表的创建与表的简单介绍,以及在oracle数据库当中的约束以及约束条件的简单介绍

系列文章目录 (3条消息) oracle数据库简介 文章目录 系列文章目录 前言 一、用户的创建 1.1、创建命令 1.2、给予scott用户权限 1.3、以scott用户进行连接登录 二、表和表的设计原则 2.1、表的概念 2.1.1、表是从属于用户的 2.1.2、表是逻辑表(概念表),不…

[比赛简介]Predict Student Performance from Game Play

比赛链接:https://www.kaggle.com/competitions/predict-student-performance-from-game-play/overview 比赛简介 本次比赛的目标是实时预测学生在基于游戏的学习中的表现。您将开发一个在最大的游戏日志开放数据集之一上训练的模型。 您的工作将有助于推进对基于…

Next.js ---未完待续....

Next.js 1.介绍2.体会服务器端渲染2.1为什么这就服务器端渲染了? 3.如何判断是否是服务器端渲染?--- 响应头信息4.文件名路由5.如何启动项目*另外1.Next.js 是基于 Webpack 的框架?1.1所以无需手动编译 TypeScript 代码 1.介绍 Next.js 是一…

【C++】C++泛型编程 | 模板初阶

🧑‍🎓个人主页:简 料 🏆所属专栏:C 🏆个人社区:越努力越幸运社区 🏆简 介:简料简料,简单有料~在校大学生一枚,专注C/C/GO的干货分…

LT8711UXE1,Type-C/DP1.2 转 HDMI2.0,内置HDCP,支持4k 60Hz向下兼容

1. 描述 LT8711UXE1 是一款高性能 Type-C/DP1.2 至 HDMI2.0 转换器,设计用于将 USB Type-C 源或 DP1.2 源连接到 HDMI2.0 接收器。LT8711UXE1 集成了一个符合 DP1.2 标准的接收器和一个符合 HDMI2.0 标准的发射器。此外,还包括两个用于 CC 通信的 CC 控…

研发/IT工程师双视角测评8大仿真平台,结果……

上一篇,我们围绕着亿万研发工程师的梦想,考察了市面上几乎所有类型的工业仿真平台,深度评测了他们本质究竟是什么,适用场景有哪些,分别能给研发和IT工程师们减轻多少工作量。 据此,我们搭建了一个工业仿真…

C++/PTA 神坛

C/PTA 神坛 题目要求解题前提及思路凹包算法概念步骤 解题思路 代码tan(y/x)及tan2(y,x)函数 总结 题目要求 在古老的迈瑞城,巍然屹立着 n 块神石。长老们商议,选取 3 块神石围成一个神坛。因为神坛的能量强度与它的面积成反比,因此神坛的面…

记录:自回归 模型在记忆 全随机序列 的潜变量 统计量爆炸现象

只是一个记录 8层12头512维度的 GPT 模型,使用它来记忆 10000 条 512长度 的无序序列,vocab_size 为100。 模型要自回归生成这些序列,不可能依赖局部推理,必须依赖全局视野,即记住前面的序列。 然后统计 最后一个no…

HF宣布在transformers库中引入首个RNN模型:RWKV,一个结合了RNN与Transformer双重优点的模型

RWKV是一个结合了RNN与Transformer双重优点的模型架构。由香港大学物理系毕业的彭博首次提出。简单来说,RWKV是一个RNN架构的模型,但是可以像transformer一样高效训练。今天,HuggingFace官方宣布在transformers库中首次引入RNN这样的模型&…

QGC局域网内连接PX4模拟器JMAVSim

环境 QGroundControl 开源地面站系统; 代码地址: https://github.com/mavlink/qgroundcontrolPX4 开源飞控系统; 代码地址: https://github.com/PX4/PX4-Autopilot QGC可以直接下载运行包. PX4 请根据代码中的说明,进行环境的配置和运行. 通过代码去build地面站和PX4的步骤见官…

【Linux 之五】 Linux中使用fdisk命令实现磁盘分区

最近由于工作的需要,初步研究了uboot中的fastboot实现方式。研究fastboot不可避免的需要了解磁盘分区的相关知识点,在linux下可以使用fdisk命令实现磁盘的分区。好了,下面步入正题。 1. 查看帮助信息(fdisk --help) …

计算机网络 - 传输层

Transport-Layer Services Transport layer, 传输层主要是完成进程(proces)到进程(process)之间的通讯的. 在传输层之下的IP协议, 提供的是best-effort的传输, 也就是对信息的正确性没有保证, 也就是IP的协议是unreliable的, TCP的协议是在IP协议至少提供可靠的数据传输. UDP…

Word批量更改图片环绕方式与=尺寸大小

前提:一份Word文档里面有100张图片,有大有小,需要将100张图片更改为统一大小,宽度与高度均为5厘米,同时环绕方式也需要改成四周型。 默认Word图片的默认环绕方式为嵌入型,需要统一更改为四周型,…

多元时间序列 | RBF径向基神经网络多变量时间序列预测(Matlab完整程序)

多元时间序列 | RBF径向基神经网络多变量时间序列预测(Matlab完整程序) 目录 多元时间序列 | RBF径向基神经网络多变量时间序列预测(Matlab完整程序)预测结果评价指标基本介绍程序设计参考资料预测结果 评价指标 训练集数据的R2为:0.99805 测试集数据的R2为:0.98351 训练…