Inheritance--继承

简介: Inheritance--继承

什么是继承?

简单来说,继承就是实现类代码复用的一种思想。

为什么要用继承?

不同类之间可能有相同/相似的类成员,把这部分成员提取出来,可以作为复用的基类。调高代码复用率。

继承的使用

我们定义了2个类,Father(父类/基类),Child(子类/派生类)

继承方式有三种,分别是pubilc/protected/private继承。

如何确定父类成员的使用权限?

取继承方式和父类成员使用权限中较小者来决定父类成员的使用权限。

(private<protected<public)

例如,Child以public方式继承Father,父类成员的private不能被访问,protected成员只能在子类中被访问,public可以在全局被访问。

关于切割/切片

1.派生类对象/指针/引用可以赋值给基类对象/指针/引用

2.基类指针/引用可以赋值给派生类指针/引用,但要强制类型转换

关于隐藏/重定义

1.若子类和父类存在同名成员,子类对象会优先访问子类中的同名成员

2.构成隐藏/重定义的条件,父类与子类中存在同名成员

关于子类的构造函数

//创建一个对象 Child c1

//程序运行结果

//子类的构造函数v2

//运行结果

结论:

1.不显示调用父类的构造函数,编译器会在初始化列表处自动调用;显示调用父类的构造函数,编译器不再调用。

2.编译器会先初始化父类,因为初始化列表的调用顺序和声明有关

关于子类的析构函数

//程序运行结果

//子类的析构函数v2

//运行结果

结论:

1.无论我们是否显示调用了析构函数,编译器都会调用析构函数

2.先构造的后析构,后构造的先析构

菱形继承中的二义性、数据冗余问题

什么是菱形继承?如下图

菱形继承的问题?

1.二义性

由于Child1与Child2都继承了Father的成员,Grandchild又继承自Child1、Child2,那么当Grandchild访问Father中的成员时就会产生二义性,究竟是访问Child1里的Father成员,还是Child2里的Father成员呢?

解决方案1,指明访问路径

为什么g1._name 没有报错?

因为grandchild类中有一个成员_name,编译器可以在g1类域中找到对应的变量,因而没有报错。

编译器寻找变量遵循“就近原则”

2.数据冗余

grandchild类对象存放了两个相同的Father

解决方案,虚拟继承

写法

此时,访问Father成员不再需要指定路径,也不再存有两份Father

实现原理

虚继承后,Child1对象和Child2对象将共用同一份Father,Child1、Child2此时不再存Father,

而是存了一个虚基表指针,指向一张虚基表,虚基表的内容是当前类地址距离基类Father的距离。

如图:(为了方便,新建了一个菱形继承的模型)

这是菱形继承后d的内存图

这是d中B的虚基表指针所指向的内容,是十六进制的14,也就是10进制的20,这意味着B与基类A相差20的距离

验证:0X001FFBA8-0x001FFB94=14

虚基表的作用?

//------------------------------------------------------------------------------------------------------------------------------//

2023.10.17补充

虚拟继承是专门针对菱形继承的

还是以上图为例,有以下语句 d._a=6;这用的上虚基表吗?用不上(对比一下d._a=6与b2->_a的汇编)

那么虚基表是干啥的呢?B是D的基类,当B类型的指针指向D类型时,如果该指针要访问_a就需要虚基表

无论b1是指向B类型还是指向D类型,他访问_a的操作都是一样的,即访问虚基表所指向的偏移量,找到对应的_a

一个类继承另一个类,是继承他的成员,两个类之间还是相互独立的。

相关文章
|
监控 Ubuntu 安全
Ubuntu开启FTP服务教程
在Ubuntu服务器上配置FTP服务是一个常见的需求,无论是用于文件分享、网站管理还是数据备份。FTP(文件传输协议)是一种用于在网络上传输文件的协议,它可以让用户通过身份验证下载或上传文件。本文将指导您如何在Ubuntu系统上安装和配置FTP服务器,以及如何管理用户权限来保证服务器的安全性。
1384 0
|
存储 机器学习/深度学习 搜索推荐
探索医学影像:如何通过ROI灰度直方图和ROI区域方格图揭示隐秘细节?
探索医学影像:如何通过ROI灰度直方图和ROI区域方格图揭示隐秘细节?
520 1
|
安全 Linux 网络安全
Windows本地搭建Emby媒体库服务器并实现远程访问「内网穿透」
Windows本地搭建Emby媒体库服务器并实现远程访问「内网穿透」
|
12月前
|
JavaScript 前端开发
JS几种拼接字符串的方法
JS几种拼接字符串的方法
184 1
|
缓存 网络协议 Linux
c++实战篇(三) ——对socket通讯服务端与客户端的封装
c++实战篇(三) ——对socket通讯服务端与客户端的封装
397 0
|
弹性计算 人工智能 运维
60分钟深度测评阿里云基于大模型构建的操作系统智能助手
OS Copilot 概要 OS Copilot 是阿里巴巴云针对Linux操作系统开发的智能助手,集成在Alibaba Cloud Linux中,利用大模型技术提供自然语言问答、命令行辅助、阿里云CLI调用和系统运维功能。它尤其适合新手,直观的交互方式提升效率。此外,OS Copilot支持在操作系统内直接管理阿里云资源,简化运维任务。目前,该助手仅在特定版本的Alibaba Cloud Linux上可用。体验者可以通过提供的链接和指南进行实操,体验其功能,如命令行的自然语言交互和环境变量配置。OS Copilot在提高用户体验和工作流集成方面的创新,预示着未来AI在操作系统中的广泛应用。
|
JavaScript 前端开发 Java
JavaScript 保留关键字
JavaScript 保留关键字
84 2
|
前端开发 Java 数据库
开源一个整合了AIGC大语言模型的SpringBoot智慧医药系统
开源一个整合了AIGC大语言模型的SpringBoot智慧医药系统
553 1
开源一个整合了AIGC大语言模型的SpringBoot智慧医药系统
|
机器学习/深度学习 算法 数据挖掘
机器学习中的监督学习与非监督学习
在机器学习领域,算法主要分为两大类:监督学习(Supervised Learning)和非监督学习(Unsupervised Learning)。这两种方法在数据处理和问题解决方面各有特点和应用场景。本文将详细介绍监督学习与非监督学习的基本概念、区别以及它们的常见应用。
686 0
|
存储 算法 Java
【C++数据结构】启航,打开新世界的大门!
【C++数据结构】启航,打开新世界的大门!
174 0