深入理解 C++ 三大特性之一 继承
欢迎来到干货小仓库!!!
今日的Commit 是明日的 Releasse,用持续交付的心态活成终身迭代的版本。

1.继承的定义
1.1定义格式

1.2继承关系和访问限定符


1.3继承基类成员访问方式的变化
| 类成员/继承方式 | public继承 | protected继承 | private继承 |
| 基类的public成员 | 派生类的public成员 | 派生类的protected成员 | 派生类的private成员 |
| 基类的protected成员 | 派生类的protected成员 | 派生类的protected成员 | 派生类的private成员 |
| 基类的private成员 | 在派生类中不可见 | 在派生类中不可见 | 在派生类中不可见 |
总结:
1. 基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
2. 基类 private 成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected 。 可以看出保护成员限定符是因继承才出现的 。3. 实际上面的表格我们进行一下总结会发现,基类的私有成员在子类都是不可见。基类的其他成员在子类的访问方式 == Min( 成员在基类的访问限定符,继承方式 ) , public>protected>private。4. 使用关键字 class 时默认的继承方式是 private ,使用 struct 时默认的继承方式是 public , 不过 最好显示的写出继承方式 。5. 在实际运用中一般使用都是 public 继承,几乎很少使用 protetced/private 继承 ,也不提倡使用protetced/private 继承,因为 protetced/private 继承下来的成员都只能在派生类的类里 面使用,实际中扩展维护性不强.
2.基类和派生类对象赋值转换
a. 派生类对象 可以 赋值给基类的对象/基类的指针/基类的引用。(向上转换/切割/切片,不会产生临时变量)
b. 基类对象 不能赋值给 派生类对象。(禁止 向下转换)

3.继承中的作用域
① 在继承体系中 基类 和 派生类 都有独立的作用域。
②子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
③ 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。
④ 注意在实际中在继承体系里面最好不要定义同名的成员。
代码示例:
示例一:相同的成员变量,默认先访问派生类中的
class Person
{
protected :string _name = "小李子"; // 姓名int _num = 111; // 身份证号
};
class Student : public Person
{
public:void Print(){cout<<" 姓名:"<<_name<< endl;cout<<" 身份证号:"<<Person::_num<< endl;cout<<" 学号:"<<_num<<endl;}
protected:int _num = 999; // 学号
};
void Test()
{Student s1;s1.Print();
};
示例二:相同的函数名,构成隐藏
// B中的fun和A中的fun不是构成重载,因为不是在同一作用域
// B中的fun和A中的fun构成隐藏,成员函数满足函数名相同就构成隐藏。
class A
{
public:void fun(){cout << "func()" << endl;}
};
class B : public A
{
public:void fun(int i){A::fun();cout << "func(int i)->" <<i<<endl;}
};
4.派生类的默认成员函数
a. 继承中 基类的成员声明 默认在派生类的成员声明的前面,初始化列表的顺序按声明顺序初始化.
b. 派生类的基类若没有默认构造,则需要在初始化列表中 对 基类进行 初始化.
c. 派生类中 会自动 基类的析构,把基类自己的资源进行释放。(不需要我们手动调用)
无需我们显示调用基类的析构----->编译器做了处理(子类析构函数完成时,自动调用基类的析构函数),由于交给我们手动释放会 无法保证先析构派生类,再析构基类。
为什么要先析构派生类 再析构基类?
由于 子类可能 使用到了 基类中的资源。
d. 编译器会统一把析构函数的函数名,进行特殊处理,处理成destructor(),由于后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同。
5.继承与友元
友元关系不能继承,也就是说基类的有源不能访问子类私有成员和保护成员。
示例:改代码编译不通过,出现语法错误
class Student;
class Person
{
public:friend void Display(const Person& p, const Student& s);
protected:string _name; // 姓名
};
class Student : public Person
{
protected:int _stuNum; // 学号
};
void Display(const Person& p, const Student& s)
{cout << p._name << endl;cout << s._stuNum << endl;
}
int main()
{Person p;Student s;Display(p, s);return 0;
}
6.继承与静态成员
若基类定义了 static静态成员,则整个体系里面只有一个这样的成员。无论派生出多少个子类都只有一个 static成员示例。(相当于只是拥有使用权)
静态成员变量属于父类和派生类。
示例:
7.复杂的菱形继承及菱形虚拟继承
单继承:一个子类只有一个直接父类时称这个继承关系为单继承

多继承:一个子类有两个或两个以上直接父类时称这个继承关系为多继承。

菱形继承:是多继承的一种特殊情况。

导致 最后一个派生类有两份 class Person 的数据,形成了 数据冗余和二义性。
解决方式:菱形虚拟继承,加上 virtual(继承公共基类的派生类上加)

7.1菱形虚拟继承底层原理
class A
{
public:int _a;
};
class B : virtual public A
{
public:int _b;
};
class C : virtual public A
{
public:int _c;
};
class D : public B, public C
{
public:int _d;
};
int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}
菱形虚拟继承的内存对象模型:


7.2习题

8.继承和组合的区别

9.继承的总结和反思

觉得不错的可以点赞+收藏咯!!!谢谢大家
相关文章:
深入理解 C++ 三大特性之一 继承
欢迎来到干货小仓库!!! 今日的Commit 是明日的 Releasse,用持续交付的心态活成终身迭代的版本。 1.继承的定义 1.1定义格式 1.2继承关系和访问限定符 1.3继承基类成员访问方式的变化 类成员/继承方式public继承protected继承private继承基类的public成员派生类的…...
类 和 对象 的介绍
对象的本质是一种新的数据类型。类是一个模型,对象是类的一个具体化实例。为类创建实例也就是创建对象。 一、类(class) 类决定一个对象将是什么样的(有什么属性、功能)。类和变量一样,有名字。 1.创建类 …...
`use_tempaddr` 和 `temp_valid_lft ` 和 `temp_prefered_lft ` 笔记250405
use_tempaddr 和 temp_valid_lft 和 temp_prefered_lft 笔记250405 以下是 Linux 系统中与 IPv6 临时隐私地址相关的三个关键参数 use_tempaddr、temp_valid_lft 和 temp_prefered_lft 的详细说明及协作关系: 📜 参数定义与功能 参数作用默认值依赖关…...
LeetCode详解之如何一步步优化到最佳解法:20. 有效的括号
LeetCode详解系列的总目录(持续更新中): LeetCode详解之如何一步步优化到最佳解法:前100题目录(更新中...)-CSDN博客 LeetCode详解系列的上一题链接: LeetCode详解之如何一步步优化到最佳解法…...
学习笔记,DbContext context 对象是保存了所有用户对象吗
DbContext 并不会将所有用户对象保存在内存中: DbContext 是 Entity Framework Core (EF Core) 的数据库上下文,它是一个数据库访问的抽象层它实际上是与数据库的一个连接会话,而不是数据的内存缓存当您通过 _context.Users 查询数据时&…...
【2020】【论文笔记】基于二维光子晶体的光控分光比可调Y——
前言 类型 太赫兹 + 分束器 太赫兹 + 分束器 太赫兹+分束器 期刊 红外与毫米波学报 红外与毫米波学报 红外与毫米波学报 作者 姜宗丹 , 李培丽 ,...
Mydumper备份数据库
介绍: MyDumper是一个MySQL逻辑备份工具。它有2个工具: mydumper负责导出 MySQL 数据库的一致备份myloader从 mydumper 读取备份,连接到目标数据库并导入备份。 这两个工具都使用多线程功能。 下载链接: https://github.com/m…...
BN测试和训练时有什么不同, 在测试时怎么使用?
我们来彻底搞懂 Batch Normalization(BN) 在训练和测试阶段的区别,以及 测试时怎么用。 🧠 一句话总结: 训练时:使用 当前 mini-batch 的均值和方差 测试时:使用 整个训练集估计的“滑动平均均值…...
JavaWeb 课堂笔记 —— 02 JavaScript
本系列为笔者学习JavaWeb的课堂笔记,视频资源为B站黑马程序员出品的《黑马程序员JavaWeb开发教程,实现javaweb企业开发全流程(涵盖SpringMyBatisSpringMVCSpringBoot等)》,章节分布参考视频教程,为同样学习…...
多GPU训练
写在前面 限于财力不足,本机上只有一个 GPU 可供使用,因此这部分的代码只能够稍作了解,能够使用的 GPU 也只有一个。 多 GPU 的数据并行:有几张卡,对一个小批量数据,有几张卡就分成几块,每个 …...
Java面试黄金宝典33
1. 什么是存取控制、 触发器、 存储过程 、 游标 存取控制 定义:存取控制是数据库管理系统(DBMS)为保障数据安全性与完整性,对不同用户访问数据库对象(如表、视图等)的权限加以管理的机制。它借助定义用户…...
如何在 Linux 上安装 Python
本指南介绍如何在Linux机器上安装 Python。Python 已成为开发人员、数据科学家和系统管理员必不可少的编程语言。它用于各种应用,包括 Web 开发、数据科学、自动化和机器学习。 本综合指南将引导您完成在 Linux 系统上安装Python的过程,涵盖从基本包管理…...
系统与网络安全------Windows系统安全(6)
资料整理于网络资料、书本资料、AI,仅供个人学习参考。 共享文件夹 发布共享文件夹 Windows共享概述 微软公司推出的网络文件/打印机服务系统 可以将一台主机的资源发布给其他主机共有 共享访问的优点 方便、快捷相比光盘 U盘不易受文件大小限制 可以实现访问…...
解决 Spring Boot 返回日期格式问题
springboot项目有个属性这样注解 DateTimeFormat(pattern "yyyy-MM-dd") private Date createTime; 表中是 create_time datetime DEFAULT NULL 只使用了 DateTimeFormat 注解来处理输入格式,但没有配置输出格式。返回给前端还是 createTime: "2…...
复古千禧Y2风格霓虹发光酸性镀铬金属短片音乐视频文字标题动画AE/PR模板
踏入时光机,重温 21 世纪初大胆、未来主义和超光彩的美学!这是一个动态的 After Effects 模板,旨在重现千禧年的标志性视觉效果——铬反射、霓虹灯发光、闪亮的金属和流畅的动态图形。无论您是在制作时尚宣传片、怀旧音乐视频还是时尚的社交媒…...
linux 安装 mysql记录
sudo apt-get install mysql-server 一直报错,按照下面的终于安装出来了 这个链接 https://cn.linux-console.net/?p13784 第 1 步:要删除 MySQL 及其所有依赖项,请执行以下命令: sudo apt-get remove --purge mysql* 第 2 步…...
如何设计一个本地缓存
想获取更多高质量的Java技术文章?欢迎访问Java技术小馆官网,持续更新优质内容,助力技术成长 Java技术小馆官网https://www.yuque.com/jtostring 如何设计一个本地缓存 随着系统的复杂性和数据量的增加,如何快速响应用户请求、减…...
NLP/大模型八股专栏结构解析
1.transformer 结构相关 (1)transformer的基本结构有哪些,分别的作用是什么,代码实现。 NLP高频面试题(一)——Transformer的基本结构、作用和代码实现 (2)LSTM、GRU和Transformer结…...
grep命令: 过滤
[rootxxx ~]# grep root /etc/passwd [rootxxx ~]# grep -A 2 root /etc/passwd -A #匹配行后两行 [rootxxx ~]# grep -B 2 root /etc/passwd -B #匹配行前两行 [rootxxx ~]# grep -C 2 root /etc/passwd -C #前后2行 [rootxxx ~]# grep -n root /…...
SpringBoot洗衣店订单管理系统设计与实现
一个基于SpringBoot的洗衣店订单管理系统的设计与实现。 系统概述 支持管理员管理顾客与店家信息、店家管理店铺与洗衣信息,以及顾客预约、查看洗衣信息与交流等功能。 部分功能模块 1. 管理员模块 顾客信息管理 店家信息管理 2. 店家模块 店铺信息管 …...
模版的特性及其编译分离
1.模版的分类 模版参数分为 类型形参 和 非类型形参 类型形参:出现在模版参数列表中,跟在class和typename之后的参数类型名称 非类型形参:就是用一个常量作为类(函数)模版的一个参数,在类(函…...
基于 Ubuntu 24.04 LTS(Noble Numbat)的完整安装指南
以下是基于 Ubuntu 24.04 LTS(Noble Numbat)的完整安装指南,整合了多平台安装方法与优化建议,涵盖物理机、虚拟机及服务器场景: 一、准备工作 1. 系统要求 硬件配置: CPU:2 GHz双核或更高 内存…...
7-12 最长对称子串(PTA)
对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定Is PAT&TAP symmetric?,最长对称子串为s PAT&TAP s,于是你应该输出11。 输入格式: 输入在一行中给出长度不超过1000的非空字符串。 输出格式&…...
NO.66十六届蓝桥杯备战|基础算法-贪心-区间问题|凌乱的yyy|Rader Installation|Sunscreen|牛栏预定(C++)
区间问题是另⼀种⽐较经典的贪⼼问题。题⽬⾯对的对象是⼀个⼀个的区间,让我们在每个区间上做出取舍。 这种题⽬的解决⽅式⼀般就是按照区间的左端点或者是右端点排序,然后在排序之后的区间上,根据题⽬要求,制定出相应的贪⼼策略&…...
搭建redis主从同步实现读写分离(原理剖析)
搭建redis主从同步实现读写分离(原理剖析) 文章目录 搭建redis主从同步实现读写分离(原理剖析)前言一、搭建主从同步二、同步原理 前言 为什么要学习redis主从同步,实现读写分析。因为单机的redis虽然是基于内存,单机并发已经能支撑很高。但是随着业务量…...
Rust切片、结构体、枚举
文章目录 切片类型字符串切片其他结构的切片 结构体结构体实例元组结构体结构体所有权输出结构体结构体的方法结构体关联函数单元结构体 枚举match语法Option枚举类if let 语句 切片类型 切片(Slice)是对数据值的部分“引用” 我们可以从一个数据集合中…...
使用人车关系核验API快速核验车辆一致性
一、 引言 随着车辆交易的日益频繁,二手车市场和金融领域的汽车抵押业务蓬勃发展。然而,欺诈和盗窃行为也时有发生,给行业带来了不小的冲击。例如,3月20日央视曝光的“新能源车虚假租赁骗补”产业链,以及某共享汽车平…...
【学习笔记】深度学习环境部署相关
文章目录 [AI硬件科普] 内存/显存带宽,从 NVIDIA 到苹果 M4[工具使用] tmux 会话管理及会话持久性[A100 02] GPU 服务器压力测试,gpu burn,cpu burn,cuda samples[A100 01] A100 服务器开箱,超微平台,gpu、…...
股票日数据使用_未复权日数据生成前复权日周月季年数据
目录 前置: 准备 代码:数据库交互部分 代码:生成前复权 日、周、月、季、年数据 前置: 1 未复权日数据获取,请查看 https://blog.csdn.net/m0_37967652/article/details/146435589 数据库使用PostgreSQL。更新日…...
Java程序设计第1章:概述
一、Hello World 1.代码: public class HelloWorld {public static void main(String[] args){System.out.println("Hello World!");} } 2.运行结果: Hello World! 二、输出姓名、学号、班级 1.题目: 编写一个Application&a…...


