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

【c++】继承(2)

hello~ 很高兴见到大家! 这次带来的是C++中关于模板进阶这部分的一些知识点,如果对你有所帮助的话,可否留下你宝贵的三连呢?
个 人 主 页: 默|笙

在这里插入图片描述


文章目录

  • 一、继承与静态成员
  • 二、多继承与菱形继承问题
    • 1. 单继承和多继承
    • 2. 菱形继承
    • 3. 虚拟继承
    • 4. 多继承中指针偏移问题
  • 三、继承和组合


继上次的继承章节—继承1


一、继承与静态成员

  1. 若基类定义了静态成员,那么整个继承体系之中也就只会有一个这样的成员。无论派生出多少个类,都只会有一个static成员实例。
class Person
{
public:string _name;static int _count;
};int Person::_count = 0;//可以通过类域访问静态成员class Student : public Person
{
protected:int _stuNum;
};int main()
{Person p;Student s;cout << "普通成员变量" << endl;cout << &p._name << endl;cout << &s._name << endl;cout << "静态成员变量" << endl;cout << &p._count << endl;cout << &s._count << endl;return 0;
}

在这里插入图片描述

  1. 可以发现,对于普通成员变量_name,对象p和对象s的_name变量地址是不相同的,它们不会共用_name,而对于静态成员变量_count,对象p和对象s的_count变量地址是相同的,这说明这两个对象是共用同一个_count的。无论再由基类继承多少个派生类,在这一个继承体系里面都是共用同一个静态成员变量_count的。

二、多继承与菱形继承问题

1. 单继承和多继承

  1. 单继承:一个派生类只有一个直接基类时称这个继承关系为单继承。
  2. 多继承:一个派生类有两个及以上的直接基类时称这个关系为多继承。多继承对象在内存中的模型是:先继承的在前面,后继承的在后面,派生类成员放到最后面(具体会在指针偏移问题处给出例子)。

在这里插入图片描述

  • 在uml图里,继承关系表示是由派生类指向基类。
  1. 如上图,对于多继承,就好比学生与老师和助教之间的关系,助教拥有双重身份,所以Assistant既需要继承Student也需要继承Teacher。也如同西红柿,西红柿既可以看作蔬菜,也可以看作是一种水果。

2. 菱形继承

  1. 菱形继承是多继承的一种特殊情况。从下图可以看出Assistant既继承了Student也继承了Teacher,而Student和Teacher都继承了同一个基类Person,那么相应的Assistant类就会继承两个Person里的成员,会有数据冗余和二义性的问题。
  2. 关于数据冗余:比如Assistant里面就包含了多份Person成员。关于二义性:在通过Assistant对象访问Person里的成员时,编译器无法分清需要访问·的是Student里的,还是Teacher里的。

在这里插入图片描述

3. 虚拟继承

  1. 数据冗余和二义性这两个问题,在虚拟继承之前,二义性可以通过指定类域来解决问题,但是数据冗余不行。而一旦解决了数据冗余的问题,二义性的问题也将会被解决。

  2. 有多继承,就不可避免的会存在菱形继承,想要解决菱形继承的问题,就需要解决菱形继承所带来的数据冗余和二义性的问题。为此虚拟继承出现了,它的关键字是virtual

  3. 虽然通过虚拟继承解决了菱形继承的问题,但是它的底层实现非常复杂,它会造成一些无法避免的损失。从这个点也可以看出,多继承算是c++的一个缺陷,在之后的一些编程语言里就没有多继承比如java。

  4. 什么时候用到关键字virtual–>在会出现数据冗余的基类(这个基类在后面的派生类会出现多个)被继承的时候在派生类的继承方式前添上virtual关键字(如class Student : virtual public Person)。

在这里插入图片描述

  1. 虚拟继承其实就是把Person这个类单独拿出来,Person不再在Student和Teacher类里面。这样就能够保证只会有一个Person。

在这里插入图片描述

  1. 尽量不要设计出菱形虚拟继承,它的底层会非常的复杂,使用也会变得复杂。
  2. 菱形虚拟继承的应用:在IO库里面有使用到。

4. 多继承中指针偏移问题

  1. 接下来我们观察一段代码:
class Student { public: int _b1; };
class Person { public: int _b2; };
class Assistant : public Student, public Teacher { public: int _d; };
int main()
{Assistant d;Student* p1 = &d;Teacher* p2 = &d;Assistant* p3 = &d;return 0;
}
  1. p1、p2、p3都指向哪里?

在这里插入图片描述

  1. d的地址存储到基类指针变量里面时,会有一个偏移量,d会先偏移一定位置使得指针指向对应的基类子对象。

三、继承和组合

  1. 组合:它表示一个类(整体)是由其他类(部分)对象共同组成的。组合是一种has-a的关系,假设B组合了A,那么每一个B对象里面都会一个A对象。就像stack的实现可以在类里面放置一个vector对象。
  2. 继承是一种 is-a 的关系,可以理解为它的每一个派生类对象都是一个特殊的基类对象
  3. 就好比可以说宝马是车,但不能说宝马有车。而像栈和顺序表之间,既可以认为栈是特殊的顺序表,也可以认为是栈里有顺序表,这种情况下继承和组合都可以使用。
  4. 通过继承生成派生类的复用一般被成为白箱复用(在继承关系中,基类的内部细节对派生类可见),这在一定程度上破坏了基类的封装特性(基类的公有和保护成员都可以被派生类使用),倘若改变基类的成员,那么派生类一般都会受影响,它们之间有很强的依赖关系,耦合度比较高。
  5. 对象组合要求被组合的对象要拥有良好定义的接口,这一般被成为黑箱复用(对象的内部细节通常都是不可见的)。被组合的类仅能使用黑箱暴露出来的接口(公有成员),改变对象所在的类,被组合的类不一定会受到影响,相比于继承的白箱复用,这种复用的耦合度比较低。
  6. 在继承和组合都可以使用的情况下,优先使用组合,但在需要实现多态的情况下,还是得用继承。组合相比于继承,它的耦合度更低,代码维护性更好。

今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~
让我们共同努力, 一起走下去!

http://www.dtcms.com/a/388962.html

相关文章:

  • 大模型提示词Prompt工程:万能公式-完整指南
  • Flask RESTful API 教程:从零实现 Python CRUD 后端服务
  • 百年奢品家电ASKO亮相IFA2025|以至臻品质绘就生活新境
  • jvm排查full gc或者humongous obj思路?如何调优?
  • 实现.NetCore集成Serilog,写入日志文件,并按日期拆分文件夹
  • [新启航]航空发动机燃烧室喷嘴孔深光学 3D 轮廓测量 - 激光频率梳 3D 轮廓技术
  • iOS 上架 App 流程全解析 苹果应用发布步骤、App Store 审核流程、ipa 文件上传与 uni-app 打包实战经验
  • 22.6 单卡A100驯服30亿参数模型!DeepSpeed ZeRO-3实战显存优化指南
  • jvm垃圾搜集器
  • 小红书开放平台笔记详情接口实战:内容解析与数据挖掘全方案
  • App 上架平台全解析,iOS 应用发布流程、苹果 App Store 审核步骤
  • BeeWorks:私有化部署即时通讯,铸就企业数字安全基石
  • (数据分析方向)Flask 动漫数据可视化分析系统(Echarts + 番剧管理・大数据)(源码)✅
  • 2025 最新版 Node.js 下载安装及环境配置教程
  • 分布式流处理与消息传递——Kafka ISR(In-Sync Replicas)算法深度解析
  • JVM(三)-- 运行时数据区
  • 从比特币到Web3:数字资产犯罪的演进史
  • godot+c#实现状态机
  • linux计划任务管理
  • excel文件导入+存储过程导入表到业务表
  • Chromium 138 编译指南 macOS 篇:构建配置与编译优化(五)
  • 基于Java与Vue的MES生产制造管理系统,实现生产流程数字化管控,涵盖计划排程、质量追溯、设备监控等功能模块,提供完整源码支持二次开发,助力智能制造升级
  • 人工智能基础:从感知机到神经网络核心知识整合​
  • 电子制造设备中螺杆支撑座如何保障精度与质量控制?
  • 东莞精密制造工厂6人共用一台服务器做SolidWorks设计
  • 智能科学与技术专业毕业设计选题推荐:计算机视觉与自然语言处理
  • 基于STM32F103C8T6与HC-08蓝牙模块实现手机连接方案
  • OpenCV 4.12.0源码解析:核心模块原理与实战应用
  • PyTorch 与 TensorFlow 的深度对比分析
  • 怀旧电玩游戏ROM合集 50T模拟器游戏资源分享