C++_继承详解
继承的概念
继承(inheritance)机制是面向对象程序设计使代码可以复用的重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。继承呈现了面向对象程序设计的层次结构,之前我们接触的复用都是函数复用,今天我们所讨论的继承是类设计层次的复用。
子类继承父类的成员后,父类的 成员函数 和 成员变量 都会变成子类的一部分,其中父类的成员函数与子类的成员函数使用的是同一个函数(构造函数除外),成员变量是每个类各自拥有,相当于把成员变量重新拷贝了一份。
注意:
- 友元关系不能被继承
- 基类若定义了static静态成员,则整个继承体系里面只有一个这样的成员。
继承方式
根据继承方式和访问限定符,共有九种继承方式:
| 类成员/继承方式 | public继承 | protected继承 | private继承 |
| 基类的public成员 | 派生类的public成员 | 派生类的protected成员 | 派生类的private成员 |
| 基类的protected成员 | 派生类的protected成员 | 派生类的protected成员 | 派生类的private成员 |
| 基类的private成员 | 在派生类中不可见 | 在派生类中不可见 | 在派生类中不可见 |
通过上面的表格可以发现:基类的其他成员在子类的访问方式 == Min(成员在基类的访问限定符,继承方式),public > protected > private。比如,基类的public成员 与 private继承方式,因为public > private,所以在派生类的访问方式为private。
基类private成员在派生类中是不能被直接访问的;protected的意义就是基类成员不能被类外的对象直接访问,但是可以被派生类直接访问。
class Person
{
public:void Print(){cout << "age:" << _age << endl;}
private:int _age = 18; // 年龄
};class Student : public Person
{
protected:int _stuid; // 学号
};
int main()
{// 虽然Student类继承了Person类,但是_age被Person设为私有// 所以Student不能直接访问_age, 但可以通过调用父类的成员函数间接访问Student st;st.Print(); // 结果为:age:18
}
基类与派生类的复制兼容转换
- 派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。叫做切片或者切割。
- 基类对象不能赋值给派生类对象
ps. Student类继承Person类

继承中的作用域
- 在继承体系中基类和派生类都有独立的作用域。
- 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
- 如果是成员函数的隐藏,只需要函数名相同就构成隐藏
下面有一道练习题,大家可以试着做一下
class A{
public:void fun()cout << "func()" << endl;
};
class B : public A
{
public:void fun(int i)cout << "func(int i)->" <<i<<endl;
};int main(){B b;b.fun();return 0;
}//不定项选择
// A选项:fun构成重载
// B选项:fun构成隐藏
// C选项:编译报错
// D选项:运行报错
答案:BC 解析:A选项,函数名相同而且在同一作用域才构成重载;B选项,正确;C选项,对象b首先会去派生类里面寻找fun,如果派生类没有,才回去基类中寻找。而本题中派生类中有fun函数,而且需要传参才可以,但是b对象调用时却没有传参,所以会编译报错,故而正确;D选项,先编译后运行,编译都报错了,根本进行不到运行这一步。
派生类的默认成员函数
“默认”的意思就是指我们不写,编译器会为我们自动生成一个,那么在派生类中,这几个默认成员函数是如何生成的呢?
- 派生类的构造函数 必须调用 基类的构造函数 初始化 基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
- 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
- 派生类的operator=必须要调用基类的operator=完成基类的复制。
- 派生类的析构函数会在被 调用完成后 在自动调用 基类的析构函数 清理基类成员。因为这样才能保证派生类对象 先清理派生类成员 再 清理基类成员的顺序。
// 派生类的拷贝构造,赋值与之类似
class Person
{
public:Person(const char* name = ""): _name(name){}Person(const Person& p): _name(p._name){}
protected:string _name;
};
class Student : public Person
{
public:Student() = default; // 强制生成默认构造// s为子类对象Student(const Student& s) // 拷贝构造// 切割,切割出子类中父类的那一部分。调用 基类的拷贝构造 来完成基类的拷贝初始化: Person(s) , _num(s._num){}
protected:int _num;
};
派生类的默认成员函数可以分为三个部分:父类的那一部分、自定义类型部分、内置类型部分。对于父类那一部分会调用父类对象相应的默认成员函数(复用)、自定义类型部分调用自定义类型的默认成员函数、内置类型不做处理。
菱形继承与菱形虚拟继承
单继承:一个子类只有一个直接父类时称这个继承关系为单继承
多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承
菱形继承: 两个派生类继承同一个基类,而同时又有某个类 同时继承了这两个派生类,这种继承被称为菱形继承,菱形继承是多继承的一种特殊情况。

从上图可以看出菱形继承存在数据冗余和二义性的问题。为了解决这个问题,后续又提出了菱形虚拟继承的概念,即在上例中的Student和Teacher的继承Person时使用虚拟继承,即可解决问题。
请看代码:
class Person
{
public :string _name ; // 姓名
};
class Student : virtual public Person // 虚拟继承
{
protected :int _num ; //学号
};
class Teacher : virtual public Person // 虚拟继承
{
protected :int _id ; // 职工编号
}相关文章:
C++_继承详解
继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。继承呈现了面向对象程序设计的层次结构,之前我们接触的复用都是函数复用,今天我们所讨…...
区块链开发解决方案有哪些
区块链开发解决方案概述 区块链开发解决方案旨在利用区块链技术构建和开发新型应用和系统,以解决各种业务问题和提升效率。区块链作为一种基于密码学的分布式账本技术,通过将交易和数据记录在不可篡改的区块中,并通过网络中的多个节点共同验…...
Express与SQLite集成教程:轻松实现数据库操作
Express使用SQLite的教程可以大致分为以下几个步骤。以下是一个详细的指南,帮助你在Express项目中集成SQLite数据库。 1. 安装必要的库 首先,你需要在你的Express项目中安装sqlite3库。打开终端或命令提示符,切换到你的项目目录,…...
Transforms的常见用法
文章目录 一、封装函数与普通函数的用法区别二、Image.open()打开图片的格式三、ToTensor打开图片格式四、ToTensor使用五、Normalize归一化使用六、Resize的使用七、Compose - Resize 使用八、RandomCrop() 随机裁剪用法 一、封装函数与普通函数的用法区…...
js 创建 React 项目
起因(目的): js 很久没写了。 react js 之前粗略看过, 最近又需要用到, 继续学习, 记录 积累。 1. 新建 React 项目 的几种方法。 官方建议使用 next 来创建 React 项目, 但是我觉得太复杂了。以后再看看. npx create-next-applatest # !!! 不建议使…...
WPF 中常用 `Transform` 类的介绍、使用示例和适用场景
WPF 中常用 Transform 类的介绍、使用示例和适用场景 使用场景解释代码示例示例代码解释 Transform 类描述使用示例适用场景TranslateTransform用于沿 X 轴或 Y 轴平移(移动)元素。xml <TranslateTransform X"50" Y"100" />移…...
ElasticSearch-DSL
查询所有 match_all 分页查询 from size深分页查询 Scroll指定字段排序 sort返回指定字段_sourcematch 短语查询 match_phrase多字段查询 multi_matchquery_string simple_query_string 关键词查询 Term 结构化搜索 前缀查询 prefix通配符查询 wildcard范围查询 range多 id 查…...
Learn ComputeShader 07 Post Processing
这次我们将使用计算机着色器对图像进行后处理。 要进行后处理需要将渲染图像从cpu传递给gpu,并在gpu对图像进行处理然后传回cpu。 首先创建一个后处理基类BasePP 首先声明需要用到的属性。 using System.Collections; using System.Collections.Generic; using …...
初始QT!
作业:了解QT文件夹初始代码的意义 QT core gui #QT工程所需得类库 core是核心库 gui图形化界面相关库类 greaterThan(QT_MAJOR_VERSION, 4): QT widgets #版本超过4.0会加上widgetsCONFIG c11 #该编辑器支持c11后的版本 # The following define makes you…...
全国大学生数据建模比赛——深度学习
全国大学生数学建模比赛中,深度学习可以成为解决复杂问题的有力手段。 一、深度学习的优势在比赛中的体现 强大的模式识别能力:深度学习模型,如卷积神经网络(CNN)和循环神经网络(RNN)࿰…...
Qt技巧(二)-滑动界面,轮询控件,循环操作控件
在Qt界面开发过程中,我们常常要对同类部件,具有同样功能的一系列部件进行操作,比如: 这个页面该怎么设计,中间的几个选项该怎么操作? 我们在主工程中添加一个设计师界面类,类名设置为“BrandF…...
003——单链表
1.链式存储的特点 逻辑(通过指针实现)上相邻,物理上可相邻可不相邻 2.结点(节点都可以) 4(&8) 8(&6) 6(&1) 1(&…...
XILINX平台下LINUX DMA驱动调研
专栏目录 高质量文章导航-持续更新中-CSDN博客 基础概念 VA:virtual address称为虚拟地址, PA:physical address称为物理地址。 CPU通过地址来访问内存中的单元,如果CPU没有MMU,或者有MMU但没有启动,那么CPU内核在取指令或者访问内存时发出的地址(此时必须是物理地址…...
Oracle数据库安装和配置指南
Oracle数据库是一款功能强大的企业级关系数据库管理系统(RDBMS),广泛应用于各种规模的企业和组织。其强大的性能和丰富的功能使其成为数据库管理的首选解决方案之一。以下是关于如何安装和配置 Oracle 数据库的详细指南。 一、准备工作 在开…...
制造业中工艺路线(工序)与产线(工作中心)关系
一.工艺路线与生产线是数字孪生中的虚实关系: 1.工艺路线为虚,生产线体为实; 2.工艺路线指导生产线的生产组织,生产线承载工艺路线的能力,把虚拟的生产信息流变成真实的产流。 二.工艺路线与生产线是数字孪生中互为“…...
目标跟踪算法——ByteTrack算法原理解析
文章目录 ByteTrack1. ByteTrack算法步骤:2. 算法解释2.1 模型初始化2.2 模型更新算法流程2.2.1 检测结果划分,划分为高分和较低分段2.2.2 高分段处理手段2.2.3 最优匹配与未匹配划分2.2.4 低分框再匹配2.2.5 未确认轨迹处理2.2.6 更新状态 2.3 匈牙利匹…...
C语言编译的过程
文章目录 1. 预处理(Preprocessing)2. 编译(Compilation)3. 汇编(Assembly)4. 链接(Linking)总结 c语言通过编译器直接编译成机器语言程序。 C语言程序的编译过程通常分为四个主要步…...
前端面试题——栈与队列、动态路由、链表
栈、队列与链表 Java数据结构栏目总结-CSDN博客 栈(Stack) 栈是一种后进先出(LIFO, Last In First Out)的数据结构。它只允许在栈顶进行添加(push)或删除(pop)元素的操作。 基本操…...
Java算法之计数排序(Counting Sort)
简介 计数排序是一种线性时间复杂度的排序算法,它不依赖于元素之间的比较,而是通过统计数组中每个元素出现的次数,然后根据这些统计信息对元素进行排序。这种算法特别适用于整数且整数的范围不是非常大时。 算法步骤 找出数组中的最大值。…...
【系统架构设计师-2012年】综合知识-答案及详解
更多内容请见: 备考系统架构设计师-核心总结索引 文章目录 【第1~2题】【第3~4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10~11题】【第12~13题】【第14~19题】【第20~21题】【第22~24题】【第25~26题】【第27~31题】【第32~33题】【第34~36题】【第37…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
