多态的概念

news2024/11/9 10:05:17

多态

    所谓的多态其实就是多种形态,它又被分为编译时多态(静态多态) 和 运行时多态(动态多态)。

静态的多态其实就是之前的模版和函数重载,今天我们主要讲动态的多态。所谓的动态多态其实就是相同的函数,完成不同的功能。

 

这就实现了明明都是用A&类型的参数,但是调用的结果不一样的情况出现。要达成这一点其实有两个地方需要注意,首先,必须是父类的指针或者引用,不然切片切不好。其次,需要父类和子类函数的返回类型、函数名、参数类型都要一样,这样,在前面加上一个virtual就可以达成虚函数的重写了。

当然这里有两个需要注意的地方:子类可以不加virtual,但是父类一定要加。另一个则是协变,这个比较少出现,它允许返回类型可以不一样,不过必须是派生类的引用或指针,也许是考虑到可能派生类里面就包含有父类的关系。

一旦上面的两个条件不满足,那就根据传入的是A,两次都调用666。所以在写多态之前先检查一下自己的条件满不满足。

 

同时它也不是非得局限于一个已有函数的另一种方法,它可以只是一个笼统的对象。

 这里有一个老六题,做完这个,想必理解会大大提升。

根据我们之前讲的,毋庸置疑这是一个虚函数的重写,之后创建了一个B类型的指针,然后再调用了test,这里是第一个坑,大伙可能觉得,这B指针不满足两个条件啊,但实际上,因为继承的关系调用test其实是把B切片了传入到A里,所以test的this是A*,满足了条件,第二个坑来了,按照我们说的,各自实现各自的,那么这里应该会打印B->0。 但是实际上打印的是B->1.

为什么呢,因为这个是重写,我用的参数并不是用B的 我用的是A的,只有内容我才按B的实现。

所以我用A的缺省参数来实现B的打印,自然就变成了B->1这么个奇怪的答案。

所以咱以后注意虚函数的重写部分就好了,派生类的缺省值就别参考了。

析构函数其实也有坑,或者说隐藏点,那就是析构函数其实都会被处理为为destructor,所以virtual加析构函数也是达成重写的,那么为什么要这么做呢。

其实就是为了应对这种情况的,站在我们的角度当然知道p1调用A的析构 p2调用B的析构,但是编译器不知道,它只会根据类型调对应的析构,那这就出现内存泄漏的问题了,所以祖师爷采取了这种方法来解决问题,所以,在父子类之中有用到new的,顺便把析构给实现重写。 也因为会被处理为destructor所以如果即使没有new,那父类和子类的析构也是构成隐藏关系的。同时子类调用构造是先调用父类再调用子类,那么到了析构,就是反过来先调用子类,再调用父类。而子类必定是包含有父类的内容的,所以子类的析构还会额外调用一次父类的析构。

到这里想必一定有粗心的兄弟,可能不会时时刻刻关注虚函数是否满足两个必备条件,所以祖师爷给了我们一个关键字 override 它可以判断你是否构成重写,如果是,那就无事发生,不然就给你报错,可以理解为虚函数专属的assert 不过它不会温和的提示你出问题,而是直接无法运行。

它会很明确的告诉你没重写。

而如果我们不想有别人重写我们的父类,那我们可以用到另一个关键字final。可以翻译理解为最终类,无法被继承和重写。 放类名后就是最终类,不能被继承,放函数后面就是不能被重写。

不过这俩是后面更新出来的,也许有一些非常老的版本是不认的。

这些概念其实如果理解了,是不用专门记的。

抽象类

其实就是之前我们不写函数实现部分,只给参数返回类型。

这玩意其实就是只给你参数,但是不给你实现,所以它不能被实例化。但是父类的指针或者引用是可以的。实现交给子类来写,子类不写光继承也不能实例化出对象来。这样也代表了它没有父类对象。完全根据子类写的实现运行。

有点类似于模版。

虚表

咱笼统的理解起来就是 带virtual的它内部都有一个隐藏的指针,所以计算大小要多算一个指针进去,这个指针准确的说是函数指针数组,它是虚函数用来存储被重写的函数的地址的。

这个vfptr其实就是虚函数的指针,它的大小取决于你这有多少个虚函数。

我们创建多少个对象,就有多少个虚表。这个过程呢就是如果你满足多态,那么我不会和正常函数一样直接调用,而是去你的虚表里面找你的地址,调用的是地址里的函数,私人订制实现。

而父类子类之间,虚表表面上其实是一个虚表,至少刚切片完是这样的,但是如果你重写了实现,那么子类的虚表就会更新覆盖之前的函数地址,所以此时虽然它表面还是父类的虚表,但是实际上它的内容已经是子类重写后的了。这也是虚函数能实现重写的本质。

知道了这一点,是不是就感觉它没那么高级了,遇到虚函数的动作都是一样的,只是它里面的地址更不更新的区别,更新了就不一样,没更新就一样。

可以看到,虚函数它里边多了很多指针跳转的步骤,一层一层找进去,然后才call的地址。

而普通的函数就很短了,我才不管你是谁,我直接根据你的地址找进去然后call就完了。

这上面也是静态绑定和动态绑定的区别,静态就是普通函数调用,虽然也能调用,但是显得有点呆板,而动态就是虚函数的调用,它就很智能,至少看起来很智能。不过动态这么多行指令效率就会比静态低一点。

小小总结一下:

虚表不同只是不同类用不同的虚表,同类其实是共享一个虚表的,因为咱的函数实现是一样的,那何必浪费内存区创建多个冗余对象呢。

而子类由两个部分组成,我们之前提到的继承下来的父类虚表和自己的虚表。表面上父类还是父类,实际上里面存的是重写后的地址。

子类的虚表又由三个部分组成:父类的虚函数地址,子类的虚函数地址,重写后的虚函数地址。

所以虚函数的本质其实是一个存虚函数指针的指针数组,而这个数组后面其实放了一个0x00000000的标记,类似于\0的作用,不过这个不是C++规定的是各个编译器定义的,vs系列会放,g++就没放。

那么虚函数表存在哪里呢,堆区?有点不太合理,因为我们并没有看到它的释放。栈?出了作用域销毁显得更不合理了,经过对比一下发现这玩意存在常量区里,不过这是vs的版本,实际上c++没规定放哪,所以可能会因为编译器的问题有所差异。

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

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

相关文章

C#搭建WebApi服务

1,OWIN的介绍 OWIN 的全称是 "Open Web Interface for .NET", OWIN 在 .NET Web 服务器和 .NET Web 应用之间定义了一套标准的接口, 其目的是为了实现服务器与应用之间的解耦,使得便携式 .NET Web 应用以及跨平台的愿望…

MongoDB事务机制

事务机制 1.事务概念 在对数据的操作的过程中,涉及到一连串的操作,这些操作如果失败,会导致我们的数据部分变化了,部分没变化。这个过程就好比如你去吃早餐,你点完餐了,并且吃完早餐了,没付钱你…

ES6标准---【五】【看这一篇就够了!!!】

目录 ES6以往文章 箭头函数的基本用法 箭头函数的用处 简化回调函数 rest参数与箭头函数结合 箭头函数使用注意点 this指向的问题 其它不存在的变量 不能使用call()、apply()、bind()方法改变this的指向 箭头函数不适用场合 定义对象时,对象方法内部包含…

信创环境下源代码防泄露解决方案

在当今数字化时代,信息安全已成为企业生存与发展的基石,尤其是在信息技术应用创新(信创)环境下,数据保护更是被提升至前所未有的高度。SDC沙盒防泄露系统以其独特的技术架构和卓越的安全性能,在信创环境中构…

ES6标准---【六】【学习ES6标准看这一篇就够了!!!】

目录 以往ES6文章 前言 对象属性的简洁表示法 一个实际例子 简介写法在打印对象时也很有用 注意 对象属性名表达式 用表达式做属性名 用表达式定义方法名 注意 对象方法的name属性 对象属性的可枚举性和遍历 可枚举性 属性的遍历 属性比那里次序规则 super关键…

图片生成PPT!首推这款一站式AI制作PPT工具!

在当今快节奏的工作中,制作一份精美的PPT演示文稿往往是一项费时费力的工作,特别是当我们需要将大量的图片转化为PPT时,传统的方法显得尤为繁琐。幸运的是,随着AI人工智能技术的飞速发展,一种更便捷地将图片转为ppt的解…

计算机毕业设计 《计算机基础》网上考试系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

Java之线程篇三

​​​​​​​ 目录 线程状态 观察线程的所有状态 线程状态及其描述 线程状态转换 代码示例1 代码示例2 线程安全 概念 线程不安全的代码示例 线程不安全的原因 线程安全的代码示例-加锁 synchronized关键字 synchronized的特性 小结 形成死锁的四个必要条件 …

Java设计模式之命令模式介绍和案例示范

一、命令模式简介 命令模式(Command Pattern)是一种行为型设计模式,它将请求封装为一个对象,从而使你可以用不同的请求对客户端进行参数化、对请求排队或记录日志,以及支持可撤销的操作。命令模式的核心思想是将发出请…

kvm 虚拟机命令行虚拟机操作、制作快照和恢复快照以及工作常用总结

文章目录 kvm 虚拟机命令行虚拟机操作、制作快照和恢复快照一、kvm 虚拟机命令行虚拟机操作(创建和删除)查看虚拟机virt-install创建一个虚拟机关闭虚拟机重启虚拟机销毁虚拟机 二、kvm 制作快照和恢复快照**创建快照**工作常见问题创建快照报错::intern…

超详细、史上最全pytorch安装教程

一、anaconda安装 1.下载 Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirrorhttps://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 这里划到最下面选择5.3.1最新版: 2.下载完成后安装 点击next 点击 I agree 选择All Us…

ignav的INS的状态更新

ignav的代码 static void updstat(const insopt_t *opt,insstate_t *ins,const double dt,const double *x0,const double *P0,double *phi,double *P,double *x,double *Q) {opt->exprn?getprn(ins,opt,dt,Q): getQ(opt,dt,Q); // //phi 状态转移矩阵 ,离散化…

算法学习攻略总结 : 入门至进阶,通关之路指南

❃博主首页 &#xff1a; <码到三十五> ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a; <搬的每块砖&#xff0c;皆为峰峦之基&#xff1b;公众号搜索(码到…

CircleProgressView 鸿蒙ArkTS自定义View实现圆形进度条

上篇的截图中除了一个上下的箭头&#xff0c;还有一个圆形进度条&#xff0c;今天我们来讲讲这个如何进行实现 我们看这个图形的构造&#xff0c;其实很简单&#xff1a;一个圆形图形&#xff0c;以及一个文本来显示进度 所以我们用一个层叠布局 绘制一个带颜色的圆形&#xff…

『功能项目』播放动画时禁止点击移动【40】

我们打开上一篇39GameObject对象池 - 第三职业的项目&#xff0c; 本章要做的事情是在第三职业播放续航攻击动画时禁止点击时触发的移动函数&#xff0c;换句话说是在播放攻击动画时禁止移动 修改脚本&#xff1a;PlayerRayClickNavigation.cs 运行项目 - 播放第三职业续航技能…

2-92 基于matlab的KPCA的TE过程的故障监测

基于matlab的KPCA的TE过程的故障监测&#xff0c;利用核主元分析法(KPCA)来进行故障检测的思想,将输入空间中复杂的非线性问题转化为特征空间中的线性问题&#xff0c;计算步骤&#xff1a;&#xff08;1&#xff09; 选择监控变量&#xff0c;收集正常工况下的各变量的样本&am…

【警告 C6031:返回值被忽略:scanf】

警告 C6031 返回值被忽略: “scanf”。 错误 C4996 scanf: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. #include <stdio.h> int max(int x, int y…

OKHttp实现原理分享

前言介绍 大约在2年半之前&#xff0c;就想写一篇关于OKHttp原理的文章&#xff0c;一来深入了解一下其原理&#xff0c;二来希望能在了解原理之后进行更好的使用。但是因为种种原因&#xff0c;一直无限往后推迟&#xff0c;最近因为我们情景智能半个月一次的分享轮到我了&…

手势识别&手势控制系统-OpenCV&Python(源码和教程)

项目特点 手部手势识别&#xff1a; 项目利用计算机视觉技术来识别手部的各种手势。这种技术可以应用于多种场景&#xff0c;比如人机交互、游戏控制、无障碍技术等。 自定义手势&#xff1a; 用户可以自定义手势&#xff0c;这意味着可以通过训练新的手势模式来扩展系统的功能…

基于vue框架的城市网约车管理系统v34td(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,司机,订单评价,完成订单,司机接单,打车订单 开题报告内容 基于Vue框架的城市网约车管理系统开题报告 一、研究背景与意义 1.1 研究背景 随着城市化进程的加速和互联网技术的飞速发展&#xff0c;网约车服务作为一种新兴的出行方…