C++从入门到入土(七)——多态

news2025/3/15 4:48:03

目录

前言

多态的概念

多态的定义

虚函数的介绍

虚函数的重写/覆盖

析构函数的重写

override和final关键字

纯虚函数和抽象类

重写/重载/隐藏总结

多态的原理

小结


前言

C++一共有三个特性,封装、继承和多态,在前面的文章中,我们分别介绍了封装和继承的概念,现在本篇文章将完成C++特性的最后一块拼图——多态。在实际生活中我们会看到这种情况,一个人有不同的身份,比如在学校的时候是老师,在家是孩子,工作了是老师;我们在买票时,成人全票,儿童半价;动物的叫声,狗是“汪汪”,猫是“喵喵”等这些都是多态的实例,多态通俗将就是一个事物的多种状态,那么有了这个认识,我们将开启多态的世界。

多态的概念

多态通俗讲就是多种状态,分为两种:编译时多态和运行时多态。我们在前面介绍的函数重载、类模板就是编译时多态,我们在这里不做过多介绍,我们今天主要介绍运行时的多态。

那么多态有什么作用呢?我们在编写代码时可能会出现下面的情况:基类当中有一个函数实现了一种功能,派生类在继承了基类后针对这个函数的功能要做出相应的调整,但函数结构大体不变,还是实现了这个功能,只不过实现方式不同,那么我们此时就可以使用多态定义这个新的函数,这样就可以保证基类代码不变的情况下,通过在派生类中的改变达到某种需求。这就是多态的核心作用

多态的定义

多态的实现需要两个条件:

1.必须是基类的指针或引用调用虚函数

2.被调用的必须是虚函数,并且完成了重写/覆盖

接下来我们将介绍虚函数和重写的概念。

虚函数的介绍

类成员函数名称前加上virtual就构成了虚函数,但是非成员函数不能用virtual修饰

虚函数的重写/覆盖

既然要保证基类代码不变的情况下,通过在派生类中添加相关功能达到某种需求,那么C++为我们提供的解决方案就是虚函数的重写/覆盖。

概念:派生类中有一个与基类完全相同的虚函数,称派生类重写了基类的虚函数
值得注意的是:派生类的虚函数如果不在前面加virtual也构成重写(但是在实际操作过程中建议在派生类中加上virtual)。重写是一种特殊的隐藏,即:不构成重写就是隐藏。

那么有了虚函数和重写后,我们可以参考下面代码,更加深入的理解多态的概念:

class Animal
{
public:
	virtual void sound()
	{
		cout << "啊啊" << endl;
	}
protected:
	string _name;
	int _weight;
	string _type;
};
class Dog :public Animal
{
public:
	virtual void sound()
	{
		cout << "汪汪" << endl;
	}
};

void func(Animal&a)
{
	a.sound();
}

上述代码运行结果如下所示:

我们可以看到,通过传不同的类就调到了不同的函数,这就是多态要完成的任务。

那么虚函数的重写可以实现不同函数的调用,这是为什么呢?实际上重写就是组合,编译器将派生类重写的函数内容与基类虚函数的声明相互组合,从而实现函数的拼接调用

析构函数的重写

C++从入门到入土(六)——继承的介绍

我们在前面继承章节中介绍默认成员函数时,对析构函数是这么说的:派生类的析构函数会在对象生命周期结束后自动调用基类的析构函数清理基类成员,因为这样才能保证先清理基类再清理派生类的顺序。(析构先子后父)这是因为析构函数在编译时统一将名称改为destructor(),与多态有关这是为什么呢?

实际上基类的析构函数是虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类析构函数构成重写,虽然它们的名称看起来不符合重写规则,但实际上编译器做了特殊处理,将他们的名称统一处理成destructor(),这样就支持了函数重写,所以析构函数在定义时建议加上virtual。

override和final关键字

C++标准对于重写的定义是比较严格的,有时候我们会因为疏忽大意导致函数无法完成重写,因此C++为我们提供了override关键字,用来检测函数是否发生重写,其定义方式是:在派生类重写的虚函数后面加上override。

如果我们不想让这个函数发生重写,那么C++标准为我们提供了final关键字,其定义方式是:在基类不想发生重写的函数后面加上final。

override和final使用如下所示:

 

纯虚函数和抽象类

纯虚函数:在虚函数后面加上=0,则这个函数就是纯虚函数,纯虚函数不需要定义实现,因为不需要重写,只要声明即可。

抽象类:包含纯虚函数的类叫做抽象类,如果派生类继承之后不重写纯虚函数,那么派生类也是抽象类,纯虚函数在某种程度上强制派生类重写虚函数,因为不重写实例化不出对象。 

重写/重载/隐藏总结

重载:两个函数在同一作用域,函数名相同,参数不同,参数的类型或个数不同,返回值可以相同,可以不同

重写:两个函数分别在基类和派生类不同的两个作用域中,函数名,参数,返回值必须相同(协变除外),两个函数必须是虚函数

隐藏:两个函数或变量分别在基类和派生类两个不同的作用域,函数名相同,两个函数只要不是重写就是隐藏

多态的原理

在讲解多态之前,我们先来看一个问题:

class A
{
public:
	virtual void func()
	{
		cout << "func()" << endl;
	}
private:
	int _a;
	char _b;
};
int main()
{
	A a;
	int size = sizeof(a);
	cout << size << endl;
	return 0;
}

你们觉得上面代码的运行结果是什么(32位)?如果根据结构体对齐的概念,我们可以知道,这个结果应该是8,但事实真是如此吗?我们运行代码:

 结果与我们推测的有所差异,这是因为什么呢?我们进行调试:

我们可以看到a当中保存了三个变量,那么应该是这个_vfptr导致大小的改变,根据后面的ptr我们可以推测这个应该是指针,那么在32位机器下,指针大小应该是四字节所以其大小变为了12字节,那么这个_vfptr是什么东西呢?实际上这个_vfptr是一个虚函数指针数组,又叫虚函数表,所有的虚函数都是存储在这个虚表当中,我们在运行过程中就是通过虚表找到每个虚函数的地址,然后实现对应的函数调用。

小结

本篇文章我们完成了C++特性的最后一块拼图——多态,通过多态我们可以更加灵活的实现代码的编辑,为我们程序的书写提供了便利,受限于博主的知识水平,可能文章当中有所纰漏,欢迎大家指正,接下来我们继续更新C++从入门到入土系列,如果觉得我的文章对您有所帮助的话,希望您能够点赞、关注加收藏,您的支持是我创作的最大动力 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2315231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新闻网页信息抽取

1. 网页信息抽取 问题定义&#xff1a;对新闻网页&#xff08;输入为HTML&#xff09;提取结构化信息&#xff0c;包括标题、发布时间、作者、正文、图片等。 动机&#xff1a;由于网页&#xff08;大多数为HTML格式&#xff09;通常带有很多标签、样式、脚本等信息&#xff0…

Docker 部署Spring boot + Vue(若依为例)

首先我们要在docker中安装好环境镜像 jdk. mysql. redis. nginx 镜像安装我们在上一篇文章中已说明&#xff0c;请大家自行查看。 下面我介绍部署步骤 部署后台jar 在你的工作目录下新建application 用来存放后台jar包 1.将打好的jar包上传 2.编写Dockerfile文件&#…

PDF文件里到底有什么?

PDF 文档结构由多个组件组成&#xff0c;这些组件决定了文本、图像和其他元素的存储和显示方式。PDF 是一种二进制文件格式&#xff0c;这意味着您无法在文本编辑器中直接编辑 PDF 文件。添加或删除一个字符都可能导致整个文件损坏&#xff01; PDF 文件结构 理解 PDF 文档结…

FANUC机器人几种常用的通讯网络及接口

FANUC机器人几种常用的通讯网络及接口 Devicenet 网络通讯接口&#xff0c;接口为5针线 (规定用的机架为 81-84&#xff09; PROFIBUS 网络通讯接口&#xff0c;针脚为2针&#xff08;规定用的机架为 67&#xff09; Intemet 网络通讯接口&#xff08;常用的网线接口&#xf…

实用插件分享:@plugin-web-update-notification/vite 的使用指南

实用插件分享&#xff1a;plugin-web-update-notification/vite 的使用指南 在前端开发的过程中&#xff0c;及时告知用户网页有更新是提升用户体验的一个重要方面。plugin-web-update-notification/vite 就是一款能够轻松实现网页更新通知功能的插件&#xff0c;下面就来详细…

IEC61850标准下MMS 缓存报告控制块 ResvTms详细解析

IEC61850标准是电力系统自动化领域唯一的全球通用标准。IEC61850通过标准的实现&#xff0c;使得智能变电站的工程实施变得规范、统一和透明&#xff0c;这大大提高了变电站自动化系统的技术水平和安全稳定运行水平。 在 IEC61850 标准体系中&#xff0c;ResvTms&#xff08;r…

人工智能与人的智能,思维模型分享【2】沉没成本

**沉没成本&#xff08;Sunk Cost&#xff09;** 是指已经发生且无法收回的成本&#xff08;时间、金钱、精力等&#xff09;。沉没成本思维模型的核心原则是&#xff1a;理性决策应基于未来可能的收益与成本&#xff0c;而非被已经无法改变的历史投入所影响。陷入沉没成本陷阱…

艾尔登复刻Ep1——客户端制作、场景切换、网络控制

需要添加的插件内容 Netcode for GameObjects&#xff1a;是一个为 Unity 游戏开发提供高级网络功能的 SDK。它的主要作用是允许开发者在其 GameObject 和 MonoBehaviour 工作流中集成网络功能&#xff0c;并且可以与多种底层传输层协议兼容。 具体内容请看&#xff1a;https:…

基于YOLO11深度学习的遥感视角地面房屋建筑检测分割与分析系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分割、人工智能

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

Java中常见的PO、VO、DAO、BO、DO、DTO、POJO、Query类解释(通俗易懂)

文章目录 先点击收藏和点赞,切勿白嫖,感谢一丶PO(persistant object)持久对象二丶VO(value object)值对象三丶DAO(Data Access Objects) 数据访问对象接口四丶BO/DO(Business Object) 业务对象层五丶DTO(Data Transfer Object) 数据传输对象六丶POJO(Plain Old Java Objects) 简…

完美解决ElementUI中树形结构table勾选问题

完美解决ElementUI中树形结构table勾选问题 实现功能效果图全选取消全选取消父节点取消某个子节点 关键代码 实现功能 1. 全选/取消全选&#xff0c;更新所有节点勾选状态 2. 勾选父/子节点&#xff0c;子/父节点状态和全选框状态更新 效果图 全选 取消全选 取消父节点 取消某…

文件解析漏洞靶场集锦详解

一、IIS解析漏洞 环境安装&#xff1a;windows2003iis6 1.目录解析 .asp文件夹中的任意文件都会被当做asp文件去执行 1.在iis6的网站根目录新建⼀个名为1.asp的文件 2. 在1.asp中新建⼀个jpg文件。内容为 <%now()%>asp代码 3.在外部浏览器中访问iis⽹站中的1.jpg 发现…

hcia华为路由器静态路由实验配置

目录 一、网络拓扑分析 二、华为路由器配置&#xff08;分设备&#xff09; 1. R1 配置 2. R2 配置 3. R3 配置 三、验证测试 拓扑图 一、网络拓扑分析 IP 地址规划&#xff1a; R1&#xff1a;E0/0/0&#xff08;12.1.1.1/24&#xff09;、E0/0/1&#xff08;192.168.1.…

Redis7——进阶篇(五)

前言&#xff1a;此篇文章系本人学习过程中记录下来的笔记&#xff0c;里面难免会有不少欠缺的地方&#xff0c;诚心期待大家多多给予指教。 基础篇&#xff1a; Redis&#xff08;一&#xff09;Redis&#xff08;二&#xff09;Redis&#xff08;三&#xff09;Redis&#x…

VBA+FreePic2Pdf 找出没有放入PDF组合的单个PDF工艺文件

设计部门针对某个项目做了一个工艺汇总报告&#xff0c;原先只要几十个工艺文件&#xff0c;组合成一个PDF&#xff0c;但后来要求要多放点PDF进去&#xff0c;但工艺文件都混在一起又不知道哪些是重复的&#xff0c;找上我让我帮忙处理一下&#xff0c;我开始建议让她重新再组…

计网面试准备

正确理解网络数据传输过程 同一路由器的不同接口属于不同局域网&#xff0c;广播只能在同一个局域网

【数据分享】1999—2023年我国地级市社会消费品零售总额和年末金融机构存贷款余额(Shp/Excel格式)

在之前的文章中&#xff0c;我们分享过基于2000-2024年《中国城市统计年鉴》整理的1999-2023年地级市的人口相关数据、染物排放和环境治理相关数据和房地产投资情况和商品房销售面积相关指标数据&#xff08;均可查看之前的文章获悉详情&#xff09;&#xff01; 本次我们分享…

PHP批量去除Bom头的方法

检查的代码&#xff1a; <?php$dir __DIR__; $files new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));foreach ($files as $file) {if ($file->isFile() && pathinfo($file, PATHINFO_EXTENSION) php) {$content file_get_contents(…

字节攻克关键技术,大模型训练效率提升1.7倍,成本节省40%

近日&#xff0c;字节豆包大模型团队开源针对 MoE 架构的关键优化技术COMET&#xff0c;该技术可将大模型训练效率提升1.7倍&#xff0c;成本节省40%。据悉&#xff0c;该技术已实际应用于字节的万卡集群训练&#xff0c;累计帮助节省了数百万 GPU 小时训练算力。 MoE&#xff…

[Pytorch报错问题解决]AttributeError: ‘nn.Sequential‘ object has no attribute ‘append‘

问题 运行深度学习代码的时候遇到了以下报错问题&#xff1a; Traceback (most recent call last):File "/home/anaconda3/envs/Text2HOI/lib/python3.9/site-packages/torch/autograd/grad_mode.py", line 28, in decorate_contextreturn func(*args, **kwargs)Fi…