[C++]继承

继承

  • 概念
    • 使用方法
    • 继承方式
    • 子类的构造与析构
  • 继承的成员
    • 继承成员在子类对象里的存放顺序
    • 成员变量
      • 普通成员变量
      • 静态成员变量
    • 成员函数
      • 普通成员函数
        • 重定义(隐藏)
      • 静态成员函数
      • 友元函数
  • 单继承与多继承
    • 概念
    • 赋值转换(切片)
    • 多继承带来的菱形继承
  • 菱形虚拟继承
    • 虚继承
      • 概念
      • 使用方法
      • 虚继承中子类对象的内容
        • 到虚继承的变量的偏移量
          • 虚基表
          • 使用指针间接寻址,而不是直接把偏移量放在对象里的原因

概念

  • 在日常开发中,我们不免会碰到这样的情况:要大量设计有相同功能的多个类,但是每个类又有一些功能是特有的,设计时就会显得很冗余
  • 为了改善这种情况,C++引入了继承的概念,继承就是指继承的类可以使用被继承的类中的指定功能

使用方法

	  派生类    继承方式 
class Student : public Person基类/父类 

继承方式

  • 简单总结继承方式
  1. 父类中,如果有私有成员:子类可以继承私有成员,但是私有成员在子类中是不可使用的,类似于隐藏
  2. 子类选择的继承方式,就是子类能继承到的最大级别:如果基类中有public成员而子类选择了protected继承方式,那么子类继承的public成员都会降级为protected

子类的构造与析构

  1. 子类的构造都是先调用基类的构造函数或拷贝函数再调用自身的拷贝/构造函数(如果基类没有默认构造函数,就要在子类的初始化列表里显示调用构造函数)
  2. 先析构子类再析构父类(这里的析构函数有用到重写,具体在多态章节会了解)

继承的成员

继承成员在子类对象里的存放顺序

class Student : public Person, public Man

  • 简单总结:先到先得,手慢靠后

成员变量

普通成员变量

  • 正常继承给子类,是属于子类的内容,可以正常使用

静态成员变量

  • 静态成员变量属于:可以继承也不可以继承的范畴,因为静态成员变量可在整个继承体系中共同使用,任何一个类对象改变了静态成员变量的值,都会影响下一个使用该变量的类对象

成员函数

普通成员函数

  • 子类继承后如果没有重写或重定义,则子类对象调用函数时,调用的是同一个函数
  • 如果重写了,就根据调用的对象来调用对应的函数(多态)
  • 如果重定义了,且调用了某一函数,就会在子类中直接使用重定义后的函数,若是重定义后的函数的参数列表不符合传入的参数,且类中没有重载,则不会跳到基类继续找匹配的函数,而是直接报错
重定义(隐藏)
  • 重定义的规则:
  1. 发生的场景在父类与子类之间
  2. 仅是函数名相同,且不构成重写

静态成员函数

  • 如同静态成员变量一样,继承体系中的类都可以使用,共享使用权

友元函数

  • 友元函数不能被继承,友元函数本质上不是类的成员,只是在类里声明能够使用类里成员的一个函数而言

单继承与多继承

概念

  • 单继承:一个子类只有一个直接父类

  • 多继承:一个子类有两个或两个以上直接父类

赋值转换(切片)

  • 派生类对象可以赋值给基类的对象 / 基类的指针 / 基类的引用。
  • 有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。
  • 基类对象不能赋值给派生类对象。
  • 基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类
    的指针是指向派生类对象时才是安全的 [多态]
    在这里插入图片描述

多继承带来的菱形继承

菱形虚拟继承

  • 如果真的有人写出了菱形继承,那么不难发现它的缺点:数据冗余性和二义性
  • 数据冗余性:最后的子类存放了两个Person父类的内容
  • 二义性:两个Person父类的内容名称完全一样,如果调用了继承的同名对象,则无法判断是要调用哪个

为了解决这个问题,C++创建了虚继承

虚继承

概念

  • 虚继承:为解决数据冗余性和二义性,让某一个父类的成员变量,每次被继承时都是直接继承父类的成员变量,而不是直接父类里父类的成员变量

使用方法

class A
{
public:int a = 10;
};
class B : virtual public A
{
public:int b = 6;
};
class C : virtual public A
{
public:int c = 3;
};class D : virtual public B, public C
{
public:int d = 0;
};int main()
{A a;B b;b.a = 100;C c;c.a = 1000;D d;return 0;
}


虚继承中子类对象的内容

  • 根据上面的图,虚继承中子类对象的内容有一点很可疑:B里面没有A的内容,那除了B本身的内容,还会有其他的内容吗
  • 答案是有的,并且还是个指针,指针指向的是:到虚继承获得的变量的偏移量大小
到虚继承的变量的偏移量

  • 多个对象时,共用一张虚基表

    事实上,D里的第一个存放的内容应该是与A的偏移量才是,这里画图失误
虚基表
  • 虚基表里存放的是:到虚继承的成员的相对位置
使用指针间接寻址,而不是直接把偏移量放在对象里的原因
  • 如果直接把偏移量放在对象里:若D被继承,由于B和C无法被修改,会导致偏移量也无法修改。
    因此通过指针间接寻找偏移量是较优的选择

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

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

相关文章

机器人构建详解:售前售后服务客服机器人与广告生成机器人的微调数据处理方法

引言 大模型(如BERT、GPT等)在自然语言处理任务中展现了强大的能力,但为了使其更贴合特定应用场景,通常需要进行微调。本文将详细讲解如何为售前售后服务的客服机器人和广告生成机器人准备高质量的微调数据,并通过具体…

8.解决跨域问题的三种方案

开启域名,单点登录后,就使用最上面的接口了

全解:Redis RDB持久化和AOF持久化

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…

使用 ASP.NET Core HttpLoggingMiddleware 记录 http 请求/响应

我们发布了一个应用程序,该应用程序运行在一个相当隐蔽的 WAF 后面。他们向我们保证,他们的产品不会以任何方式干扰我们的应用程序。这是错误的。他们删除了我们几乎所有的“自定义”标头。为了“证明”这一点,我构建了一个中间件&#xff0c…

回调机制详解

一、什么是回调: 回调是一种双向的调用模式,程序模块之间通过这样的接口调用完成通信联系,回调的核心就是回调方将本身即this传递给调用方,这样调用方就可以在调用完毕之后再告诉回调方它想要知道的信息。 回调函数用于层间协作&…

CUDA 计时功能,记录GPU程序/函数耗时,cudaEventCreate,cudaEventRecord,cudaEventElapsedTime

为了测试GPU函数的耗时,可以使用 CUDA 提供的计时功能:cudaEventCreate, cudaEventRecord, 和 cudaEventElapsedTime。这些函数可以帮助你测量某个 CUDA 操作(如设置设备)所花费的时间。 一、记录耗时案例 以下是一个示例程序&a…

异步操作,promise、axios

一、异步操作(异步编程)、同步操作 异步操作是指在编程中,某个任务的执行不会立即完成,同时不会阻塞后续代码的执行。在异步操作中,程序可以继续运行,并在异步任务完成时得到通知并处理结果。这与同步操作…

Ansible的yum和saltstack的哪个功能相似

Ansible的yum和saltstack的哪个功能相似 在 Ansible 和 SaltStack 中,Ansible 的 yum 模块 和 SaltStack 的 pkg 模块 功能相似。它们都用于管理软件包,支持安装、升级、删除和查询等操作。 Ansible 的 yum 模块 用途: 专门用于基于 Red Hat …

JVM 面试题相关总结

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…

基于BiLSTM-CRF的中文电子病历命名实体识别

声明:博客未经允许禁止抄袭转载。 前言 最近有粉丝在后台私信我能不能更一篇关于命名实体识别(NER,Named Entity Recognition)的经典模型BiLSTM-CRF的实战文章,前段时间有点忙所有一直没有更新,趁着最近有点空,满足一…

k8s 优雅监控jvm及dump heap的方案探讨

背景 k8s cluster 的健康检测失败会主动重启pod,而大部份情况下健康检测失败都是由full gc引起的。往往发生重启时已经没有条件dump heap排查full gc的原因。 如何监控 为了避免因健康检测失败而导致的pod重启,我们需要实施有效的监控策略,这…

TPM 2.0:安全固件的新标准

得益于可信计算组 ( TCG ) 推出的全新 TPM 2.0规范,联网设备可以更好地抵御网络攻击,并且不太可能受到错误的攻击。 制造商将可信平台模块 (TPM) 附加到设备上,以帮助用户和管理员验证其身份、生成和存储加密密钥以及确保平台完整性。 在 T…

ensp实验-vrrp多网关配置

一、交换机与路由的配置区别 1. 角色定义交换机: Master 或 Backup: 交换机通常作为 Master 或 Backup 设备参与 VRRP,负责在主设备故障时接替其工作。路由器: Master 或 Backup: 路由器同样可以作为 Master 或 Backup 设备…

黑盒测试方法

‌黑盒测试是一种软件测试方法,它通过向系统提供输入并检查输出结果来验证系统的功能是否符合需求。‌黑盒测试主要关注软件的功能性,而不是其内部结构或工作原理。以下是几种常见的黑盒测试顺序方法: 场景设计法‌: 通过模拟实际…

游戏引擎学习第38天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾上次的内容。 我们之前讨论了将精灵放在屏幕上,但颜色错误的问题。问题最终查明是因为使用了一个调整工具,导致文件的字节顺序发生了变化。重新运行“image magic”工具对一些大图像进行重新处理后&am…

aws(学习笔记第十六课) 使用负载均衡器(ELB)解耦webserver以及输出ELB的日志到S3

aws(学习笔记第十六课) 使用负载均衡器(ELB)以及输出ELB的日志到S3 学习内容: 使用负载均衡器(ELB)解耦web server输出ELB的日志到S3 1. 使用负载均衡器(ELB) 全体架构 使用ELB(Elastic Load Balancer)能够解耦外部internet访问和web server之间的耦合&#xff0c…

深入理解C#的TCPIP通信机制

本文还有配套的精品资源,点击获取 简介:在分布式系统和实时数据交换应用中,C#作为一种现代面向对象编程语言,利用其***命名空间下的Socket类,提供强大的TCP/IP通信功能。本文将探讨C#中TCP/IP通信的基本概念、使用方…

高项 - 项目管理原则与项目绩效域

个人总结,仅供参考,欢迎加好友一起讨论 博文更新参考时间点:2024-12 高项 - 章节与知识点汇总:点击跳转 文章目录 高项 - 项目管理原则与项目绩效域项目管理12条原则原则1:成为勤勉、尊重和关心他人的管家 (p202)原则…

仿真技术助力高尔夫球打破传统设计局限,实现球杆强大的功能

Altair近日宣布与业内领先的高尔夫装备制造商 Cleveland Golf 开展合作,以设计新款 HiBore XL 球杆。借助 Altair 先进的仿真与设计技术,Cleveland Golf 不断刷新高尔夫装备的行业标准,并在球杆产品设计方面实现突破。 Cleveland Golf 借助 A…

python字符串处理基础操作总结

1.去掉空格或者特殊符号 input_str.strip() #去掉所有空格 input_str.lstrip() #去掉左边空格 input_str.rstrip() #去掉右边空格 def print_hi():input_str 今天天气不错,风和日丽 out input_str.strip()print(input_str)print(out)if __name__ __main__:print…