[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无法被修改,会导致偏移量也无法修改。
    因此通过指针间接寻找偏移量是较优的选择

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MetaGPT 安装

1. 创建环境 conda create -n metagpt python3.10 && conda activate metagpt2. 可编辑方式安装 git clone --depth 1 https://github.com/geekan/MetaGPT.git cd MetaGPT pip install -e .3. 配置 metagpt --init-config运行命令,在C盘位置C:\Users\325…

ros项目dual_arm_pick-place(urdf文件可视化查看)

前言 一直想写一些项目的讲解,今天(2024.12.05)可以说正式开始了。 dual_arm_pick-place项目,是关于两个机械臂协同传递物品。 正文 这次的话,给大家讲一下里面的urdf文件。 这篇文章主要来看一下项目中的urdf文件…

如何在 IntelliJ IDEA 中为 Spring Boot 应用实现热部署

文章目录 1. 引言2. 准备工作3. 添加必要的依赖4. 配置 IntelliJ IDEA4.1 启用自动编译4.2 开启热部署策略 5. 测试热部署6. 高级技巧7. 注意事项8. 总结 随着现代开发工具的进步,开发者们越来越重视提高生产力的特性。对于 Java 开发者来说,能够在不重启…

工业-实时数据采集

1.编写新的 Flume 配置文件,将数据备份到 HDFS 目录 /user/test/flumebackup 下,要求所有主题 的数据使用同一个 Flume配置文件完成。 1. 配置概览 Flume 的主要任务是从多个来源(如日志文件)读取数据,经过处理后通过接收器(Sink)存储到目标系统(如 HDFS)。在此配置…

springSecurity认证流程

Spring Security 是spring家族中的一个安全管理框架。相比于另一个安全框架Shiro,它提供更丰富的功能和社区资源,但也较难上手。所以一般大项目用spring Security,小项目用Shiro。 一般web应用需要认证和授权,这也是spring Secur…

LinuxUDP编程

由于UDP是无连接、尽力传输的,所以Server端绑定完IP、端口号后,使用recvfrom可以阻塞等待客户端的数据,而且Client端通过sendto发送的数据包直接发送到互联网(也是基于IP、端口号)这种操作是不担保Server端是否收到的&…

Nginx基本介绍及conf文件的作用

文章目录 前言一、Nginx基本介绍1.1 what is Nginx ?1.2 Nginx中的三个概念1.3 nginx安装1.4 运行nginx 二、nginx配置文件conf2.1 conf文件组成部分2.1.1 全局块2.1.2 events块2.1.3 http块 三、其他概念3.1 nginx惊群3.2 负载均衡 总结 前言 本文将介绍nginx的基…

Docker打包SpringBoot项目

一、项目打成jar包 在进行docker打包之前,先确定一下,项目能够正常的打成JAR包,并且启动之后能够正常的访问。这一步看似是可有可无,但是能避免后期的一些无厘头问题。 二、Dockerfile 项目打包成功之后,需要编写Doc…

GitLab基础环境部署:Ubuntu 22.04.5系统在线安装GitLab 17.5.2实操手册

文章目录 GitLab基础环境部署:Ubuntu 22.04.5系统在线安装GitLab 17.5.2实操手册一、环境准备1.1 机器规划1.2 环境配置1.2.1 设置主机名1.2.2 停止和禁用防火墙1.2.3 更新系统 二、GitLab安装配置2.1 安装GitLab所需的依赖包2.2 添加GitLab存储库2.2.1 将GitLab存储…

【前端开发】HTML+CSS+JavaScript前端三剑客的基础知识体系了解

前言 🌟🌟本期讲解关于HTMLCSSJavaScript的基础知识,小编带领大家简单过一遍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 …

6. 一分钟读懂“抽象工厂模式”

6.1 模式介绍 书接上文,工厂方法模式只能搞定单一产品族,遇到需要生产多个产品族时就歇菜了。于是,在需求的“花式鞭策”下,程序员们再次绷紧脑细胞,创造出了更强大的抽象工厂模式,让工厂一次性打包多个产品…

数仓技术hive与oracle对比(五)

附录说明 附录是对测试过程中涉及到的一些操作进行记录和解析。 oracle清除缓存 alter system flush shared_pool; 将使library cache和data dictionary cache以前保存的sql执行计划全部清空,但不会清空共享sql区或者共享pl/sql区里面缓存的最近被执行的条目。刷…

CEEMDAN-CPO-VMD二次分解(CEEMDAN+冠豪猪优化算法CPO优化VMD)

CEEMDAN-CPO-VMD二次分解(CEEMDAN冠豪猪优化算法CPO优化VMD) 目录 CEEMDAN-CPO-VMD二次分解(CEEMDAN冠豪猪优化算法CPO优化VMD)效果一览基本介绍程序设计参考资料 效果一览 基本介绍 首先运用CEEMDAN对数据进行一次分解&#xff…

UG NX二次开发(Python)-UIStyler-选取点

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、设计一个UI界面3、创建长方体的代码4、需要引入的库5、测试验证1、前言 采用Python语言进行UG NX二次开发的资料比较少,我本来不是很认可采用Python进行二次开发的,但是近期有读者咨询…

后端-时间格式问题的解决办法

方法一:在需要的地方直接加 方法二:在全局写一个springmvc的消息转换器类

哪款云手机适合多开?常用云手机功能对比

在全球化和数字化时代,云手机以其独特的灵活性和高效性,成为多账号运营和数字营销的热门工具。云手机能够解决传统设备管理的诸多痛点,例如账号关联、硬件成本高等问题。本文将为您推荐多款优质云手机品牌,帮助您选择最适合的工具…

Qt 小项目 学生管理信息系统

主要是对数据库的增删查改的操作 登录/注册界面: 主页面: 添加信息: 删除信息: 删除第一行(支持多行删除) 需求分析: 用QT实现一个学生管理信息系统,数据库为MySQL 要求&#xf…

第三部分:进阶概念 7.数组与对象 --[JavaScript 新手村:开启编程之旅的第一步]

第三部分:进阶概念 7.数组与对象 --[JavaScript 新手村:开启编程之旅的第一步] 在 JavaScript 中,数组和对象是两种非常重要的数据结构,它们用于存储和组织数据。尽管它们都属于引用类型(即它们存储的是对数据的引用而…

Redis设计与实现读书笔记

目录 Redis设计与实现[^1]第一部分:数据结构与对象简单动态字符串SDS的基础定义与C字符串的差别常数获取长度杜绝缓冲区溢出减少修改字符串时带来的内存重分配次数二进制安全函数兼容 链表链表和链表节点的实现 字典字典的实现哈希表定义哈希表节点定义字典定义 哈希…

笔记04--零基础创建个人本地大模型知识库ollama+Dify

ollma安装 官网下载直接下一步下一步即可,没有魔法的朋友可以留言,文章中所用到的文件也给打包了,大家可以直接下载使用通过云盘下载使用。 链接: https://pan.baidu.com/s/12zF9MpQtg1bnMDAQayaSyg 提取码: n9rm 官网地址:http…