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…...
ClearerVoice-Studio在客服系统中的实战应用:语音质检与分析
ClearerVoice-Studio在客服系统中的实战应用:语音质检与分析 1. 引言 你有没有遇到过这样的情况:客服中心的通话录音总是夹杂着键盘敲击声、背景交谈声,甚至还有空调的嗡嗡声?想要从中提取关键信息做质量分析,却发现…...
蓝桥杯双阶乘解答
题目:代码:import java.math.BigInteger;import java.util.Scanner;// 1:无需package// 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan new Scanner(System.in);//在此输入您的代码...BigInteger…...
【常见开发问题】SQL注入示例及防范措施介绍
SQL注入示例及防范措施介绍 文章目录 SQL注入示例及防范措施介绍 一、SQL注入简介 二、SQL防注入方法 三、总结 一、SQL注入简介 SQL注入是将Web页面的原URL、表单域或数据包输入的参数,修改拼接成SQL语句传递给Web服务器,进而传给数据库服务器以执行数据库命令。其根本原因…...
信息安全等级保护制度定级 → 备案 → 建设整改 → 等级测评(由具备资质的第三方机构执行) → 监督检查
一、网络安全防护技术 防火墙(Firewall):部署在网络边界(如企业出口),基于预设规则(IP/端口/协议/应用层策略)控制进出流量,实现访问过滤与网络隔离。分为包过滤、状态检…...
Qwen3.5-4B-Claude-OpusAI应用:轻量级推理服务嵌入内部知识库方案
Qwen3.5-4B-Claude-OpusAI应用:轻量级推理服务嵌入内部知识库方案 1. 模型概述 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是基于Qwen3.5-4B的推理蒸馏模型,特别强化了结构化分析、分步骤回答、代码与逻辑类问题的处理能力。该版本以GGUF量…...
Flutter应用安全保护:代码混淆的重要性与Android/iOS混淆步骤详解
前言 本文将会和大家说下保护代码的重要性,和如何给程序加上混淆编译功能。 尽可能的不要在你的程序中写死各种服务秘钥,比如 oss 容易被盗用。 参考 https://docs.flutter.dev/deployment/obfuscatehttps://www.guardsquare.com/blog/obstacles-in-…...
Claude读论文系列(七)
SkillSieve 精读笔记 论文标题: SkillSieve: A Hierarchical Triage Framework for Detecting Malicious AI Agent Skills arXiv: 2604.06550 | 2026-04-09 作者: Yinghan Hou(Imperial College London) Zongyou Yang…...
在超大数据集下 DuckDB 与 MySQL 查询速度对比姿
一、什么是urllib3? urllib3 是一个用于处理 HTTP 请求和连接池的强大、用户友好的 Python 库。 它可以帮助你: 发送各种 HTTP 请求(GET, POST, PUT, DELETE等)。 管理连接池,提高网络请求效率。 处理重试和重定向。 支…...
Git 版本管理下的 Pixel Mind Decoder 模型迭代与部署实践
Git 版本管理下的 Pixel Mind Decoder 模型迭代与部署实践 1. 为什么需要版本管理 在AI项目开发中,我们经常遇到这样的困扰:上周还能正常运行的模型,这周突然效果变差了;团队里不同成员使用的模型版本不一致导致结果无法复现&am…...
OpenClaw多语言支持:Qwen3-4B处理跨境文档翻译与格式转换
OpenClaw多语言支持:Qwen3-4B处理跨境文档翻译与格式转换 1. 为什么需要本地化多语言文档处理 上个月我收到一份日文技术手册,需要翻译成英文和韩文版本。尝试过主流云翻译平台后,发现三个痛点:一是敏感内容上传公有云有风险&am…...
