你明白C++中的多态吗?(暑假提升-多态专题)

内不欺己,外不欺人。———孔子


有趣的多态

  • 1、前言
  • 2、概念
  • 3、多态定义与产生条件
  • 4、多态的重要组成成员-(虚函数)
  • 5、虚函数的重写(覆盖)
  • 6、辅助关键字override与final(了解即可)
  • 7、重载,重定义(隐藏),重写(覆盖)
  • 8、抽象类
  • 9、多态的原理
    • 9、1、虚函数表
    • 9、2、多态原理

1、前言

在最开始,我会讲明白分那么多的小标题的目的就是方便不懂多态的人能够有大概的框架,知道多态的能够有目的的去复习。所以标题分那么多请不要见怪。多多包涵。
在这篇文章中已经讲过了C++中的一个重要的特性-继承,想回顾一下的可以点击一下链接,复习复习。接下来我们将进行多态的讲解,其中也有一部分内容和继承比较相似,容易搞混,所以我尽力的讲清楚多态的特点和注意点,如果是继承的问题想不明白的话,可以看看我之前的文章,其中也算是讲的比较详细的。

2、概念

多态,也可以理解是多种状态。不同的状态完成不同的事情,可能是目的一样,但是不同的对象,实现的结果却是不同的。
意思是类产生的对象(存在继承的关系),在实现函数的时候,调用的是同一个函数名,但是执行出来的结果却是大相径庭的。

3、多态定义与产生条件

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。
比如:Student继承了 Person。Person对象买票全价,Student对象买票半价。
除此之外,想要实现多态还需要两个条件。
1. 必须通过基类的指针或者引用调用虚函数
2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

在这里插入图片描述

重写与继承中的隐蔽有区别或者说是重定义是不一样的!
在继承中,函数的重定义只需要函数名字相同就能够构成重定义,但是对于多态的实现必须要三个要素都相同函数名,参数,返回值
其中不管是基类还是派生类,在进行多态函数调用的时候,必须是用基类的引用或者是指针。

4、多态的重要组成成员-(虚函数)

和虚继承相似,虚函数的定义也会用到virtual关键字,但是关键字的位置是不一样的,怎么说呢,就好像是&的操作一样,在不同的场景之下,可能是取地址也有可能是引用,所以要注意区别,分别看待。在这里插入图片描述

5、虚函数的重写(覆盖)

虚函数的重写就是在子类继承之后在其中有一个和父类三要素都相同的虚函数,称子类的虚函数重写了基类的虚函数。
注意: 在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用。

class Person 
{
public:virtual void BuyTicket() { cout << "买票-全价" << endl; } 
};
class Student : public Person 
{
public:virtual void BuyTicket() { cout << "买票-半价" << endl; 
}

析构函数的重写,与众不同。析构函数即使不加virtual关键字也会重写,当然了,即使是名字不同也还是会重写。名字的不同是在我们编辑的时候定义的不同的名字,但是对于编译器来说,到编译的那一步的时候,已经将所有的析构函数统一名字了。编译后析构函数的名称统一处理成destructor

6、辅助关键字override与final(了解即可)

override与final关键字能够很好的帮助我们检查多态中函数重写可能存在的问题。
**override:**检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。
final: 修饰虚函数,表示该虚函数不能再被重写

7、重载,重定义(隐藏),重写(覆盖)

三种概念实现的东西,相对而言是类似的,能够概括的认为,表面上是为了调用相同的东西,但是细微的区别能够又有着不同的处理方法,可能还会是不同的效果。
所以三种不同的操作,定义之间对于区别的掌握也是十分重要的

在这里插入图片描述

8、抽象类

抽象类的形成就是在虚函数的最后加上“=0”,抽象类不能够实例化,如果继承的话,形成的派生类如果不重写虚函数也不能够实例化对象。所以抽象类的出现,一定程度上要求严格了虚函数重写,因为不重写就不能实例化出对象,也就没有下面之后的事情。同时抽象类也称为纯虚函数(我个人看到这个名词就感觉像是不能产生对象的意思)。

class Car
{
public:virtual void Drive() = 0;
};class Benz :public Car
{
public:virtual void Drive(){cout << "Benz-舒适" << endl; }
};

另外,纯虚函数体现了接口的继承观念。

9、多态的原理

9、1、虚函数表

就像是在继承中的虚继承一样,其中作为基类的A在内存中存放的位置是在最底下,但是同样的,为了保证是相同的a,B和C中在内存中的第一个地址的位置存放着虚基表来帮助找到a的位置,能够修改和得到a的值。这篇文章中还有图的解释,这里就不再多赘述了。
**有趣的是,多态中的原理和虚继承好像还有点相似,**其中多态中,有着另一种表虚函数表。为了更能够理解虚函数表的作用,我们先从一个题目来入手。

// 这里常考一道笔试题:sizeof(Base)是多少? 
class Base
{
public:virtual void Func1(){cout << "Func1()" << endl;}
private:int _b = 1;
};

答案是8byte而不是只有4个byte,那么多出来的4byte是什么?那其实是一个指针,一个虚函数表指针。当然了,如果一个基类中有多个虚函数的话,只会存在一个虚函数表指针,也就是意味着在刚刚的Base类中,即使还有别的虚函数,最后Base的大小也还是4byte。虚函数表指针简称也叫做虚表指针。
但是,如果是多继承下来的子类中的虚函数表可能不止一个。
在这里插入图片描述
编译器,实现多态的方法是靠在第一个元素位置的地址指向的地址,调用不同的函数。
满足多态的条件:那么这里的调用生成的指令,就会去指向对象中的虚表中找对应的函数进行调用。
不满足多态的条件:直接就确定函数的地址,而不去虚函数表里面找,因为直接找到了。
为什么重写也称为是覆盖呢?因为在地层中,重写条件满足后,当前对象中的虚函数表就会改写,原本从父类继承下来的相同的虚函数就会换成子类中的函数指针的位置,这样的步骤看做为覆盖是十分合理的。

9、2、多态原理

了解了虚函数表之后,想一想在第三个标题中图片的内容,其实在底层的实现中也就是像这个样子的。在这里插入图片描述
**虚表:**虚函数表,存的虚函数,目标实现多态。
**虚基表:**存的是当前位置距离虚基类部分的位置的偏移量,防止存在菱形继承的二异性问题。
Tip: 每一个存在的数据都会存放在计算机内部,而计算机拥有着。栈,堆,静态区,常量区。那么对于虚表来说,存放在哪呢?在这里插入图片描述
由此可见,vs上的虚表是存在于常量区之中的。

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

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

相关文章

PHP老照片修复文字识别图像去雾一键抠图微信小程序源码

&#x1f50d;解锁复古魅力&#xff0c;微信小程序黑科技大揭秘&#xff01;老照片修复&更多神奇功能等你来试&#xff01; &#x1f4f8; 【老照片修复&#xff0c;时光倒流的美颜术】 你是否珍藏着一堆泛黄的老照片&#xff0c;却因岁月侵蚀而模糊不清&#xff1f;现在…

实验02 黑盒测试(组合测试、场景法)

1. 组合测试用例设计技术 指出等价类划分法和边界值分析法通常假设输入变量相互独立&#xff0c;但实际情况中变量间可能存在关联。全面测试&#xff1a;覆盖所有输入变量的所有可能组合&#xff0c;测试用例数量随输入变量的增加而指数增长。 全面测试需要对所有输入的各个取…

2008年上半年软件设计师【上午题】真题及答案

文章目录 2008年上半年软件设计师上午题--真题2008年上半年软件设计师上午题--答案 2008年上半年软件设计师上午题–真题 2008年上半年软件设计师上午题–答案

按模版批量生成定制合同

提出问题 一个仪器设备采购公司&#xff0c;商品合同采购需要按模版生成的固定的文件&#xff0c;模板是固定的&#xff0c;只是每次需要替换信息&#xff0c;然后打印出来寄给客户。 传统方法 如果手工来做这个事情&#xff0c;准备好数据之后&#xff0c;需要从Excel表格中…

高效应对网络攻击,威胁检测响应(XDR)平台如何提升企业应急响应能力

在数字化时代&#xff0c;企业面临的网络攻击威胁持续增加&#xff0c;如恶意软件、勒索软件、钓鱼攻击、DDoS攻击等。这些威胁不仅危及企业数据安全、系统稳定&#xff0c;还损害了品牌形象和市场信任。随着云计算、大数据、物联网的广泛应用&#xff0c;企业网络攻击面扩大&a…

MAVLink代码生成-C#

一. 准备Windows下安装环境 Python 3.3 – 官网链接下载Python future模块 –pip3 install future TkInter (GUI 工具). – python for Windows自带&#xff0c;无需下载环境变量PYTHONPATH必须包含mavlink存储库的目录路径。 –set PYTHONPATH你的mavlink源码路径 源码下载在…

【昆工主办|7月昆明】第三届绿色建筑、土木工程与智慧城市国际会议(GBCESC 2024)

随着全球城市化进程的加速&#xff0c;绿色建筑、土木工程与智慧城市等议题逐渐成为了行业内外关注的焦点。在这一背景下&#xff0c;第三届绿色建筑、土木工程与智慧城市国际会议&#xff08;GBCESC 2024&#xff09;的召开&#xff0c;无疑将为相关领域的研究者、学者及从业者…

原理和组成

能力要素&#xff1a;&#xff08;1&#xff09;人员要素&#xff1a;“正确选人”。&#xff08;2&#xff09;过程要素&#xff1a;“正确做事”。&#xff08;3&#xff09;技术要素&#xff1a;“高效做事”。&#xff08;4&#xff09;资源要素&#xff1a;“保障做事”。…

【ARM】MDK-解决Flexnet服务的error:-13.66

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 记录MDK网络版部署服务器error &#xff1a;-13.66的问题解决方案&#xff0c;后续有相关发现持续更新。 2、 问题场景 在客户的服务器上部署Flexnet服务&#xff0c;将license文件检查过后&#xff0c;确认MAC地址…

如何才能半个月学习完自动化测试,成功跳槽涨薪?

一直想写类似的文章&#xff0c;但是一直没有时间&#xff0c;正好乘此周末&#xff0c;终于可以写写我的见解了<关于如何学习自动化测试>&#xff0c;其实自动化测试的知识很宽泛&#xff0c;具体细分又可以分为&#xff1a;Web自动化测试&#xff08;PythonSelenium&am…

全新UI自助图文打印系统小程序源码 PHP后端 附教程

最新自助图文打印系统和证件照云打印小程序源码PHP后端&#xff0c;为用户用户自助打印的服务&#xff0c;包括但不限于文档、图片、表格等多种格式的文件。此外&#xff0c;它们还提供了诸如美颜、换装、文档打印等功能&#xff0c;以及后台管理系统&#xff0c;方便管理员对打…

【密码学】公钥密码的基本概念

在先前我写的密码学体制文章中谈到&#xff0c;现代密码学分为两大体制&#xff0c;介绍了一些有关对称密码体制诸如流密码和分组密码的内容。本文的主要内容则切换到公钥密码体制&#xff08;又称非对称密码体制&#xff09;&#xff0c;简述了公钥密码体制的基本思想和应用方…

六个Python实用技巧,大幅提升你的编程效率!

关注星标&#xff0c;每天学习Python新技能 Python作为当下最流行的编程语言之一&#xff0c;以其简洁易懂的语法和强大的第三方库支持&#xff0c;深受开发者的喜爱。在实际开发中&#xff0c;掌握一些实用的Python小技巧&#xff0c;可以大大提升编程效率和代码质量。 本文…

院内导航:如何用科技破解就医找路难题

自2019年开始“院内导航”被纳入医院智慧服务评估体系以来&#xff0c;到2023年改善就医服务升级的部署&#xff0c;每一步都见证了我国医疗卫生体系向智能化、人性化迈进的坚实步伐。 面对庞大复杂的医院环境与日益增长的就诊需求&#xff0c;如何让患者在茫茫人海中迅速找到就…

CSDN回顾与前行:我的创作之旅——2048天的技术成长与感悟

CSDN回顾与前行&#xff1a;我的创作之旅——2048天的技术成长与感悟 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 前言 时光荏苒&#xff0c;岁月如梭。转眼间&#xff0c;从我在CSDN上写下第一篇技术博客《2-6 带头结点的链式表操作集…

Springcloud双重预防管理体系平台危险作业票子系统-计算机毕业设计源码48672

摘 要 随着企业生产规模的扩大和生产技术的提高&#xff0c;双重预防管理体系逐渐成为企业安全生产的重要手段。在双重预防管理体系中&#xff0c;危险作业票管理是其中的关键环节之一&#xff0c;对于预防生产事故和保障生产安全具有重要作用。 为了更好地管理危险作业票&…

移动应用:商城购物类,是最常见的,想出彩或许就差灵犀一指

在移动应用中&#xff0c;商城购物类的非常常见&#xff0c;模式也非常成熟&#xff0c;想要设计的出彩也是有难度的&#xff0c;这次分享一些不同的。

C语言之Const关键字与指针

目录 1 前言2 变量与指针的储存方式3 const int *var;int *const var&#xff1b;const int *const var&#xff1b;理解与区分4 总结 1 前言 实际开发过程中经常遇到const关键字作用于指针的情况&#xff0c;例如&#xff1a;const int *var;int *const var&#xff1b;const…

Linux开发板(正点原子阿尔法_IMX6U)QT5.12.9交叉编译到ARM开发板(已解决)

问题记录&#xff1a;Qt下ctrlR直接构建项目&#xff0c;然后在build-01_led-Desktop_Qt_5_12_9_GCC_64bit-Debugz中将构建的执行文件&#xff0c;scp到ARM开发板下&#xff0c;发现通过指令./01_led后出现以下报错。 问题原因&#xff1a;因为Qt构建默认使用的是64bit的gcc&am…

群辉NAS同步Android手机日历日程

目录 一、安装套件 二、手机导出日历日程 三、NAS套件导入日历 四、获得DAVx5登陆链接 五、手机配置 六、验证 上一篇文章我们解决了Android手机与群辉NAS的通讯录的同步,这期我们说说如何同步Android手机的日历中的日程到群辉NAS。 看过上篇文章的伙伴知道,Android需要…