当前位置: 首页 > news >正文

嵌入式养成计划-40----C++菱形继承--虚继承--多态--模板--异常

九十四、菱形继承

94.1 概念

  • 菱形继承又称为钻石继承,
  • 是由公共基类派生出多个中间子类,又由中间子类共同派生出汇聚子类,
  • 汇聚子类会得到多份中间子类从公共基类继承下来的数据成员,会造成空间浪费,没有必要。

所以存在一个问题:

  • 汇聚子类会得到多份中间子类从公共基类继承下来的数据成员,会造成空间浪费,没有必要。
  • 会多次对公共基类的数据成员初始化,或者释放。
  • 如何避免?

94.2 形式

   A     --------公共基类/   \
B     C   -------中间子类\   /D     --------汇聚子类
  • 上面那个问题的解决方法:虚继承

九十五、虚继承

95.1 作用

  • 使汇聚子类仅获得一份经中间子类从公共基类继承下来的数据成员。

95.2 格式

  • 关键字 :virtual
  • 在中间子类的继承方式前加 virtual
class 类名:virtual 继承方式 类名   //中间子类,可多继承
{中间子类自己的内容;
};

95.3 注意

  • 虚继承之后,只保留一份中间子类从公共基类继承下来的数据成员,
  • 但是不知道保留哪个中间子类的,所以就会自动调用公共基类的无参构造函数,
  • 如果想使用公共基类的有参构造函数,则需要在汇聚子类中调用公共基类的有参构造函数。

九十六、多态

  • 静态多态(在编译时加载)—> 如 :函数重载
  • 动态多态(在运行时加载)

96.1 啥是多态

  • 多态 :一种形式 拥有 多种状态
  • 例如 :一个人,在不同环境下有着不同的状态,也有不同的 属性 和 功能

  • 多态:父类的指针或者引用,指向或者初始化子类的对象,调用子类对父类重写的函数,进而使用子类的功能。

96.2 函数重写

  • 要求 :
    1. 两个类之间必须要有继承关系
    2. 子类和父类有同名同类型的函数
    3. 父类中的该函数必须是虚函数

96.3 虚函数

  • 关键字 :virtual
  1. 在函数前加 virtual ----->虚函数
  2. 虚函数满足继承,
    如果父类中函数是虚函数,那么继承到子类中,该函数还是虚函数,
    如果子类继续被继承,那么“孙类”中的该函数还虚函数…

96.4 赋值兼容规则

  • 父类的指针或者引用,可以指向或者初始化子类的对象
  • 父类指针指向的仅仅只是子类中继承父类的那段空间
    在这里插入图片描述

96.5 多态中,实现函数重写的原理

  1. 类中有虚函数时,虚函数都会有一个虚指针
  2. 虚指针在类的最前面,指向了虚函数表,虚函数表里记录虚函数
  3. 虚指针和虚函数表是实现多态的重要机制
    在这里插入图片描述

96.6 虚析构函数

  • 因为父类指针指向子类对象,只作用与子类从父类继承下来的那片特殊空间,
  • 释放父类指针,只会把父类指针作用的那块空间释放,子类自己拓展的空间没有得到释放,从而造成内存泄漏。

虚析构函数 :如果把父类中析构函数设置成虚析构函数,那么子类拓展的空间就会被一起释放,虚析构函数也满足继承。

示例 :

#include <iostream>
using namespace std;class Person
{
private:string name;
public:Person() {}Person(string name):name(name){}virtual ~Person(){}  //虚析构函数
};
class Stu:public Person
{
private:int id;
public:Stu() {}Stu(string n, int id):Person(n),id(id){}~Stu(){}
};
int main()
{Person *ptr = new Stu("zhangsan", 1001);delete ptr;  //如果没有虚析构函数的话,只释放父类指针作用的空间,子类//拓展的空间并没有得到释放,会造成内存泄漏。解决方案:虚析构函数return 0;
}

96.7 纯虚函数

  • 当父类中的虚函数只用来被子类重写,并且没有需要去完成的功能,那么一般将该虚函数设置成纯虚函数。

  • 格式:

    virtual 函数返回值类型 函数名(形参列表) = 0 ; //纯虚函数
    //纯虚函数 是在父类中声明,子类中实现
    

    在这里插入图片描述

96.8 抽象类

  • 概念: 抽象类中至少有一个纯虚函数,抽象类不能具体的实例化一个对象,一般是用来被继承的。
    不能实例化对象,只能执行子类对象

  • 如果父类中有纯虚函数,表示父类是抽象类,
    子类继承后,如果没有对父类中纯虚函数做重写,则子类也是一个抽象类,不能实例化一个对象。

例如 :

#include <iostream>
using namespace std;class A
{
private:int a;
public:virtual void show() = 0;//纯虚函数  
};class B :public A
{
private:int b;
public:
};int main()
{//B a;  不能实例化一个对象return 0;
}

96.9 C++中虚函数与纯虚函数的区别

  1. 虚函数和纯虚函数可以定义在同一个类中,含有纯虚函数的类被称为抽象类,而只含有虚函数的类不能被称为抽象类。

  2. 虚函数可以被直接使用,也可以被子类重载以后,以多态的形式调用,而纯虚函数必须在子类中实现该函数才可以使用,因为纯虚函数在基类有声明而没有定义。

  3. 虚函数和纯虚函数都可以在子类中被重载,以多态的形式被调用。

  4. 虚函数和纯虚函数通常存在于抽象基类之中,被继承的子类重载,目的是提供一个统一的接口。

  5. 虚函数的定义形式:virtual{};纯虚函数的定义形式:virtual { } = 0;在虚函数和纯虚函数的定义中不能有static标识符,原因很简单,被static修饰的函数在编译时要求前期绑定,然而虚函数却是动态绑定,而且被两者修饰的函数生命周期也不一样。

九十七、模板

  • 模板就是建立一个通用的模具,大大提高代码的复用性。
  • C++除面向对象编程思想外,还有另一种编程思想,泛型编程,主要利用的技术是 模板
  • C++提供了两种重要的模板机制:函数模板 和 类模板

生活中的模板 :
在这里插入图片描述
在这里插入图片描述

97.1 模板的特点

  1. 模板是通用的,不是万能的
  2. 模板只是一个框架

97.2 函数模板

97.2.1 作用

  • 函数模板,就是建立一个通用的函数,
  • 其返回值类型,或者参数类型不具体制定,用一个虚拟的类型来代替。

97.2.2 格式

template<typename T>
函数的定义

如 :

template <typename T>
T fun(T x, T y)  //建立了一个通用的函数,实现数据类型之和
{return x+y;
}

template -------> 创建模板
typename -------> 表明其后是一种数据类型,typename还可以用class代替
T -----> 表示数据类型,也可以用其他代替

调用时 :

cout << fun(1,2) << endl;
cout << fun(1.3,1.4) << endl;
cout << fun('0', '1') << endl;

97.3 类模板

97.3.1 作用

  • 建立一个通用的类, 类中的 成员变量 的类型 不具体制定,用一个虚拟类型来代替

97.3.2 格式

template<typename T>
类的定义

template -------> 创建模板
typename -------> 表明其后是一种数据类型,typename还可以用class代替
T -----> 表示数据类型,也可以用其他代替

九十八、异常

  • 作用 :可以优雅的解决异常

  • 实现步骤

    1. try包裹可能产生异常的地方
    2. 在产生异常的条件下,用 throw抛出异常
    3. try后面的 catch语句中接收异常,并在 catch后的代码块中处理异常

示例 :

#include <iostream>
using namespace std;int fun(int x, int y)
{if(y!=0){return x/y;}else{throw -1;  //抛出异常}
}
int main()
{try{fun(9,0); //把可能发生异常的地方用try包裹起来cout << "hello 啊" << endl;        }catch (int e){if(e == -1){cout << "分母为0,不合法" << endl;}}return 0;
}

小作业:

比喻:
动物园的讲解员和动物表演
动物园里有一位讲解员,他会为每种动物表演做简单的介绍,如狮子、大象、猴子等。提示:在这个场景中,我们可以将动物比作是不同的类,而每种动物表演则是类中的函数。讲解员则是一个基类,他可以根据每种动物的特点和表演,进行相应的介绍。
具体过程如下:定义一个基类 Animal,其中有一个虛函数perform(),用于在子类中实现不同的表演行为。

我写的

#include <iostream>
using namespace std;// base_class
class Animal
{
private:string name;
public:Animal() {}Animal(string name):name(name) {}Animal(const Animal &other):name(other.name){}Animal &operator=(const Animal &other){name = other.name;return *this;}virtual ~Animal(){}virtual void perform() = 0;string get_name(){return this->name;}
};class Lion:virtual public Animal
{
public:Lion() {}Lion(string name):Animal(name) {}Lion(const Lion &other):Animal(other){}Lion &operator=(const Lion &other){Animal::operator=(other);return *this;}~Lion(){}void perform() {cout << Animal::get_name() + " : " << "河东狮吼" << endl;}
};class Elephant:virtual public Animal
{
public:Elephant() {}Elephant(string name):Animal(name) {}Elephant(const Elephant &other):Animal(other){}Elephant &operator=(const Elephant &other){Animal::operator=(other);return *this;}~Elephant(){}void perform() {cout << Animal::get_name() + " : " << "象群践踏" << endl;}
};class Monkey:virtual public Animal
{
public:Monkey() {}Monkey(string name):Animal(name) {}Monkey(const Monkey &other):Animal(other){}Monkey &operator=(const Monkey &other){Animal::operator=(other);return *this;}~Monkey(){}void perform() {cout << Animal::get_name() + " : " << "专业偷桃" << endl;}
};int main()
{Animal *p = nullptr;Lion l("狮子狗");Elephant e("孟获");Monkey m("孙猴子");p = &l;p->perform();p = &e;p->perform();p = &m;p->perform();return 0;
}

在这里插入图片描述

相关文章:

嵌入式养成计划-40----C++菱形继承--虚继承--多态--模板--异常

九十四、菱形继承 94.1 概念 菱形继承又称为钻石继承&#xff0c;是由公共基类派生出多个中间子类&#xff0c;又由中间子类共同派生出汇聚子类&#xff0c;汇聚子类会得到多份中间子类从公共基类继承下来的数据成员&#xff0c;会造成空间浪费&#xff0c;没有必要。 所以存…...

C++入门指南:类和对象总结友元类笔记(下)

C入门指南:类和对象总结友元类笔记&#xff08;下&#xff09; 一、深度剖析构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 二、static成员2.1 概念2.2 特性 三、友元3.1 友元函数3.2 友元类 四、 内部类4.1 概念4.2 特征 五、拷贝对象时的一些编译器优化六、深…...

ctfshow web入门 php特性 web136-web140

1.web136 还有一种写文件的命令时tee命令 payload&#xff1a; : ls /|tee 1 访问1下载查看文件1发现根目录下有flag cat /f149_15_h3r3|tee 2 访问下载查看文件22.web137 call_user_func <?php class myclass {static function say_hello(){echo "He…...

sshpass传输文件提示Host key verification failed.

1. sshpass功能简述 sshpass指令可用于A服务器向B服务器传输文件或执行某些指令。 2. 传输文件指令 基本传输命令&#xff1a;sshpass -p 远程服务器登录密码 scp 本地路径文件 远程服务器登录用户名远程服务器IP地址:远程服务器文件保存路径 示例&#xff1a; sshpass -p 1…...

Maven系列第5篇:私服详解

maven系列目标&#xff1a;从入门开始开始掌握一个高级开发所需要的maven技能。 这是maven系列第5篇。 整个maven系列的内容前后是有依赖的&#xff0c;如果之前没有接触过maven&#xff0c;建议从第一篇看起&#xff0c;本文尾部有maven完整系列的连接。 环境 maven3.6.1 …...

深入解析Spring Cloud Gateway的GlobalFilter

文章目录 摘要引言GlobalFilter的作用使用GlobalFilter默认的GlobalFilter自定义GlobalFilter 示例代码配置GlobalFilter配置文件方式代码方式 高级用法&#xff1a;重写GlobalFilter思路代码实现 结论参考文献 摘要 本文将详细介绍Spring Cloud Gateway中的GlobalFilter&…...

ffmpeg的重采样计算

最近在看ffmpeg的重采样计算逻辑&#xff0c;有一句话没大看懂 dst_nb_samples av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) src_nb_samples, dst_rate, src_rate, AV_ROUND_UP); &#xff0c;各种请教之后&#xff0c;记录如下。 重采样后的总样本数 为什么要涵盖重采…...

Go HTTP 调用(上)

哈喽大家好&#xff0c;我是陈明勇&#xff0c;今天分享的内容是 Go HTTP 调用。如果本文对你有帮助&#xff0c;不妨点个赞&#xff0c;如果你是 Go 语言初学者&#xff0c;不妨点个关注&#xff0c;一起成长一起进步&#xff0c;如果本文有错误的地方&#xff0c;欢迎指出&am…...

STM32Cube高效开发教程<基础篇>(一)----概述

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。    本专栏博客参考《STM32Cube高效开发教程(基础篇)》,有意向的读者可以购买正版书籍辅助学习,本书籍由王维波老师、鄢志丹老师、王钊老师倾力打造,书籍内容干货满满。 一、 STM32系列…...

汽车RNC主动降噪算法DSP C程序实现

汽车RNC主动降噪算法C程序 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,车载...

Java21虚拟线程完整用法

方式1 Thread.startVirtualThread(new Task());方式2 Thread virtualThread Thread.ofVirtual().name("Virtual Thread").unstarted(new Task()); virtualThread.start();方式3 Thread.ofVirtual().name("Virtual Thread").start(new Task());方式4 Th…...

Vue 中的 nextTick 方法

nextTick的背景 Vue 使用虚拟 DOM&#xff08;Virtual DOM&#xff09;和异步更新策略来实现高效的视图更新。当你修改 Vue 实例的数据时&#xff0c;Vue 并不会立即更新真实的 DOM&#xff0c;而是将更新操作加入到队列中&#xff0c;在下一个事件循环周期&#xff08;微任务…...

TypeScript React(上)

目录 扩展学习资料 TypeScript设计原则 TypeScript基础 语法基础 变量声明 JavaScript声明变量 TypeScript声明变量 示例 接口 (标准类型-Interface) 类型别名-Type 接口 VS 类型别名 类型断言:欺骗TS&#xff0c;肯定数据符合结构 泛型、<大写字母> 扩展学习…...

Linux 安全 - LSM源码分析

文章目录 前言一、简介1.1 DAC 和 MAC1.2 LSM 调用流程图 二、LSM相关数据结构2.1 struct security_hook_list2.2 union security_list_options2.3 structure security_hook_heads 三、security_bprm_check四、LSM 源码分析3.1 early_security_init3.2 security_init3.2.1 secu…...

第一次汇报相关问题

深度学习现在已经学习到了Mini-Batch&#xff0c;early-stop等针对特定场景优化的算法了。 代码已经实现了一个L层的神经网络的构建了 论文看了一些综述 主要思考的两个方向&#xff1a;云计算和嵌入式 云计算&#xff1a;分布式机器学习、联邦学习、服务器负载均衡等 嵌入式&…...

[产品体验] GPT4识图功能

[产品体验] GPT4识图功能 图片配文字超强的OCR能力知识问答多图解释 打开chatgpt的时候突然发现能用识图了&#xff0c;赶紧去体验一下&#xff0c;大大的震撼… 图片配文字 超强的OCR能力 我传上去的图片并不清晰… 还能准确识别&#xff0c;orz &#xff01; 知识问答 多…...

《3D 数学基础》几何检测-最近点

目录 1. 直线上的最近点 2. 射线上的最近点 3. 点到平面的距离 4. 圆或球上的最近点 5. AABB上的最近点 1. 直线上的最近点 q是距离q的最近点&#xff0c;也就是q在直线上的投影。 其中p是直线上的点&#xff08;向量表示&#xff09;&#xff0c;n是直线的法向量&#x…...

动态规划 -背包问题-详解

问题 注&#xff1a;大佬对此类问题的解法&#xff1a;动态规划背包问题总结 给你一个由 不同 整数组成的数组 nums &#xff0c;和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 示例 1&#xff…...

Bootstrap-- 媒体特性

最大、最小宽度例子&#xff1a; 横屏与竖屏例子&#xff1a; 宽度比与像素比例子&#xff1a;...

c# 用非递归的写法实现递归

最近写代码碰到了一个bug&#xff0c;就是递归次数太多爆堆栈了&#xff0c;然后就写了一个递归工具来解决这个问题。 using System; using System.Collections.Generic;/// <summary> /// 递归工具 /// </summary> public static class RecursionTool {//递归方式…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解

文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一&#xff1a;HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二&#xff1a;Floyd 快慢指针法&#xff08;…...

GAN模式奔溃的探讨论文综述(一)

简介 简介:今天带来一篇关于GAN的,对于模式奔溃的一个探讨的一个问题,帮助大家更好的解决训练中遇到的一个难题。 论文题目:An in-depth review and analysis of mode collapse in GAN 期刊:Machine Learning 链接:...