【C++】继承(下)

大家好,我是苏貝,本篇博客带大家了解C++的继承(下),如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • 5.继承与友元
  • 6.继承与静态成员
  • 7.复杂的菱形继承及菱形虚拟继承
  • 8.继承的总结和反思
  • 9.笔试面试题

5.继承与友元

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员,就像父母的朋友不是你的朋友一样
在这里插入图片描述

6.继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。父类静态成员属于当前类,也属于当前类的所有派生类,因此无论派生出多少个子类,都只有一个static成员实例

在这里插入图片描述
在这里插入图片描述

如果我们想知道A及其派生类实例化了多少对象,就可以定义一个static变量

在这里插入图片描述

在这里插入图片描述

7.复杂的菱形继承及菱形虚拟继承

单继承:一个子类只有一个直接父类时称这个继承关系为单继承

在这里插入图片描述

多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承
在这里插入图片描述

多继承的定义如上图的Assistant,只需要在原本继承的基础上加逗号和其它基类即可

菱形继承:菱形继承是多继承的一种特殊情况。比如助教,对老师来说,他是个学生;对学生来说,他是个老师。因此他有学生和老师两个身份,就继承了学生类和老师类
在这里插入图片描述

菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性(后面介绍)的问题。
在这里插入图片描述

数据冗余:在Assistant的对象中Person成员会有两份。
二义性:Student和Teacher类都有_name,无法明确知道访问的是哪一个

在这里插入图片描述
在这里插入图片描述

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和 Teacher的继承Person时使用虚拟继承(在继承公共的基类时用虚拟继承),即只保存1份Person的成员,就不会造成数据冗余,二义性也就解决了。需要注意的是,虚拟继承不要在其他地方去使用。

在这里插入图片描述
在这里插入图片描述

在上面这种菱形继承中,虚拟继承用在菱形的腰部B和C,那下图的用在哪呢?也是B和C,virtual放在有公共基类(A)的类中
在这里插入图片描述

虚拟继承解决数据冗余和二义性的原理:
为了研究虚拟继承原理,我们给出了一个简化的菱形继承继承体系,再借助内存窗口观察对象成员的模型。

下面是不加虚拟继承的菱形继承
在这里插入图片描述

在这里插入图片描述

我们可以从内存窗口看出,D里面包含2份A的成员,会导致数据冗余和二义性。因为类D先继承B,再继承C,因此D类的对象d中,先出现类B的成员,再是类C的成员,最后是类D的成员。
同理,如果类D先继承C,再继承B,那么D类的对象d中,先出现类C的成员,再是类B的成员,最后是类D的成员。

下面我们加上虚拟继承
在这里插入图片描述
在这里插入图片描述

我们可以从内存窗口看出,D里面只包含1份A的成员,不会导致数据冗余和二义性。而且这时的B和C类的成员中都不包含本来有的A类成员,并且都存储了一个地址(0x00677bdc和0x00677be4,机器是小端存储),我们来看看这2个地址指向的内容

在这里插入图片描述
在这里插入图片描述

原来地址指向的空间(叫虚基表)里存放的是与A的成员的偏移量(还有其它的内容,这里不做介绍)

为什么要存偏移量?在切片的时候有用。将d赋值给类B的对象bb,就要把D类中B类那部分切来赋值过去,可是这里的B类的成员不包括A类的成员,因此B类保存的地址就能找到与A类的成员的偏移量,就能找到A类的成员,才能最终将B类的成员赋值给bb

在这里插入图片描述

多继承本身没有问题,但有多继承就可能导致菱形继承

总结:实践中可以设计多继承,但切记不要设计菱形继承,因为太复杂,容易出现各种问题

问:下面哪个选项是正确的?
在这里插入图片描述

A:p1 == p2 == p3
B:p1 < p2 < p3
C:p1 == p3 != p2
D:p1 != p2 != p3

答案:C
在这里插入图片描述

问:下面哪个选项是正确的?
在这里插入图片描述

A:p1 == p2 == p3
B:p1 < p2 < p3
C:p2 == p3 != p1
D:p1 != p2 != p3

答案:C
在这里插入图片描述

问:下面程序的结果是什么?
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

类D的对象定义时先走初始化列表,再走函数体,所以”class D”一定在最后。先声明的先走初始化列表,D类中先声明的是B类,B继承A,所以A比B更先声明,再声明C,最后D。因此A->B->C->D

8.继承的总结和反思

1、 很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度及性能上都有问题。
2、 多继承可以认为是C++的缺陷之一,很多后来的语言都没有多继承,如Java。
3、 继承和组合
组合是什么?将一个类(如A)作为成员变量放在另一个类中(如B)
在这里插入图片描述

public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。

适合is-a的关系,如人和学生,就用is-a。适合has-a的关系,如汽车和轮胎,就用has-a。is-a和has-a都可以,如链表和栈,就用has-a。即优先使用对象组合,而非类继承

继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类有很大的影响。派生类和基类间的依赖关系很强,耦合度高。

对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被封装。

实际尽量多去用组合。组合的耦合度低,代码维护性好。不过继承也有用武之地的,有些关系就适合继承那就用继承,另外要实现多态,也必须要继承。类之间的关系可以用继承,可以用组合,就用组合。

9.笔试面试题

1、 什么是菱形继承?菱形继承的问题是什么?
2、 什么是菱形虚拟继承?如何解决数据冗余和二义性的
3、 继承和组合的区别?什么时候用继承?什么时候用组合?

复用的常见体现:
1、 函数逻辑的复用
2、 模板
3、 继承
4、 组合


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

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

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

相关文章

基于LLM的路由在专家混合应用:一种新颖的交易框架,该框架在夏普比率和总回报方面提升了超过25%

“LLM-Based Routing in Mixture of Experts: A Novel Framework for Trading” 论文地址&#xff1a;https://arxiv.org/pdf/2501.09636 摘要 随着深度学习和大语言模型&#xff08;LLMs&#xff09;的不断进步&#xff0c;混合专家&#xff08;MoE&#xff09;机制在股票投资…

Med-R2:基于循证医学的检索推理框架:提升大语言模型医疗问答能力的新方法

Med-R2 : Crafting Trustworthy LLM Physicians through Retrieval and Reasoning of Evidence-Based Medicine Med-R2框架Why - 这个研究要解决什么现实问题What - 核心发现或论点是什么How - 1. 前人研究的局限性How - 2. 你的创新方法/视角How - 3. 关键数据支持How - 4. 可…

【Blazor学习笔记】.NET Blazor学习笔记

我是大标题 我学习Blazor的顺序是基于Blazor University&#xff0c;然后实际内容不完全基于它&#xff0c;因为它的例子还是基于.NET Core 3.1做的&#xff0c;距离现在很遥远了。 截至本文撰写的时间&#xff0c;2025年&#xff0c;最新的.NET是.NET9了都&#xff0c;可能1…

C++ Primer 迭代器

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

2 [GitHub遭遇严重供应链投毒攻击]

近日&#xff0c;有黑客针对 Discord Top.gg 的GitHub 账户发起了供应链攻击&#xff0c;此次攻击导致账户密码、凭证和其他敏感信息被盗&#xff0c;同时也影响到了大量开发人员。 Checkmarx 在一份技术报告中提到&#xff0c;黑客在这次攻击中使用了多种TTP&#xff0c;其中…

【AudioClassificationModelZoo-Pytorch】基于Pytorch的声音事件检测分类系统

源码&#xff1a;https://github.com/Shybert-AI/AudioClassificationModelZoo-Pytorch 模型测试表 模型网络结构batch_sizeFLOPs(G)Params(M)特征提取方式数据集类别数量模型验证集性能EcapaTdnn1280.486.1melUrbanSound8K10accuracy0.974, precision0.972 recall0.967, F1-s…

基于Spring Security 6的OAuth2 系列之七 - 授权服务器--自定义数据库客户端信息

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…

Jupyterlab和notebook修改文件的默认存放路径的方法

文章目录 1.缘由2.操作流程2.1找到默认的路径2.2创建配置文件2.3修改配置文件内容2.4注意事项 1.缘由 我自己使用jupyterlab的时候&#xff0c;打开是在这个浏览器上面打开的&#xff0c;但是这个打开的文件路径显示的是C盘上面路径&#xff0c;所以这个就很麻烦&#xff0c;因…

算法题(56):旋转链表

审题&#xff1a; 我们需要根据k的大小把链表向右移动对应次数&#xff0c;并返回移动后的链表的头结点指针 思路&#xff1a; 根据提示中的数据大小我们发现&#xff1a;k的值可以远大于节点数。 也就是说我们对链表的操作存在周期&#xff0c;如果k%len0&#xff0c;说明我们…

新月军事战略分析系统使用手册

新月人物传记&#xff1a; 人物传记之新月篇-CSDN博客 相关故事链接&#xff1a;星际智慧农业系统&#xff08;SAS&#xff09;&#xff0c;智慧农业的未来篇章-CSDN博客 “新月智能武器系统”CIWS&#xff0c;开启智能武器的新纪元-CSDN博客 “新月之智”智能战术头盔系统&…

金山打字游戏2010绿色版,Win7-11可用DxWnd完美运行

金山打字游戏2010绿色版&#xff0c;Win7-11可用DxWnd完美运行 链接&#xff1a;https://pan.xunlei.com/s/VOIAYCzmkbDfdASGJa_uLjquA1?pwd67vw# 进入游戏后&#xff0c;如果输入不了英文字母&#xff08;很可能是中文输入状态&#xff09;&#xff0c;就按一下“Shift”键…

99,[7] buuctf web [羊城杯2020]easyphp

进入靶场 <?php// 使用 scandir 函数扫描当前目录&#xff08;即脚本所在目录&#xff09;下的所有文件和文件夹// 该函数会返回一个包含目录下所有文件和文件夹名称的数组$files scandir(./); // 遍历扫描得到的文件和文件夹名称数组foreach($files as $file) {// 使用 …

Hot100之图论

200岛屿数量 题目 思路解析 把访问过的格子插上棋子 思想是先污染再治理&#xff0c;我们有一个inArea&#xff08;&#xff09;函数&#xff0c;是判断是否出界了 我们先dfs&#xff08;&#xff09;放各个方向遍历&#xff0c;然后我们再把这个位置标为0 我们岛屿是连着…

html中的表格属性以及合并操作

表格用table定义&#xff0c;标签标题用caption标签定义&#xff1b;用tr定义表格的若干行&#xff1b;用td定义若干个单元格&#xff1b;&#xff08;当单元格是表头时&#xff0c;用th标签定义&#xff09;&#xff08;th标签会略粗于td标签&#xff09; table的整体外观取决…

LabVIEW如何有效地进行数据采集?

数据采集&#xff08;DAQ&#xff09;是许多工程项目中的核心环节&#xff0c;无论是测试、监控还是控制系统&#xff0c;准确、高效的数据采集都是至关重要的。LabVIEW作为一个图形化编程环境&#xff0c;提供了丰富的功能来实现数据采集&#xff0c;确保数据的实时性与可靠性…

进阶数据结构——双向循环链表

目录 前言一、定义与结构二、特点与优势三、基本操作四、应用场景五、实现复杂度六、动态图解七、代码模版&#xff08;c&#xff09;八、经典例题九、总结结语 前言 这一期我们学习双向循环链表。双向循环链表不同于单链表&#xff0c;双向循环链表是一种特殊的数据结构&…

S4 HANA明确税金汇差科目(OBYY)

本文主要介绍在S4 HANA OP中明确税金汇差科目(OBYY)相关设置。具体请参照如下内容&#xff1a; 1. 明确税金汇差科目(OBYY) 以上配置点定义了在外币挂账时&#xff0c;当凭证抬头汇率和税金行项目汇率不一致时&#xff0c;造成的差异金额进入哪个科目。此类情况只发生在FB60/F…

在线知识库的构建策略提升组织信息管理效率与决策能力

内容概要 在线知识库作为现代企业信息管理的重要组成部分&#xff0c;具有显著的定义与重要性。它不仅为组织提供了一个集中存储与管理知识的平台&#xff0c;还能够有效提升信息检索的效率&#xff0c;促进知识的创新和利用。通过这样的知识库&#xff0c;企业可以更好地应对…

【汽车电子软件架构】AutoSAR从放弃到入门专栏导读

本文是汽车电子软件架构&#xff1a;AutoSAR从放弃到入门专栏的导读篇。文章延续专栏文章的一贯作风&#xff0c;从概念与定义入手&#xff0c;希望读者能对AutoSAR架构有一个整体的认识&#xff0c;然后对专栏涉及的文章进行分类与链接。本文首先从AutoSAR汽车软件架构的概念&…

DeepSeek-R1:通过强化学习激励大型语言模型(LLMs)的推理能力

摘要 我们推出了第一代推理模型&#xff1a;DeepSeek-R1-Zero和DeepSeek-R1。DeepSeek-R1-Zero是一个未经监督微调&#xff08;SFT&#xff09;作为初步步骤&#xff0c;而是通过大规模强化学习&#xff08;RL&#xff09;训练的模型&#xff0c;展现出卓越的推理能力。通过强…