虚函数+多态实现原理(一个冷门知识)

news/2024/11/17 23:31:50/

目录

多态实现

虚函数定义

先说原理

抛出问题

探究多态底层

冷门知识


多形态的大海

多态实现

完成类多态体现,多态两个条件:
虚函数重写
父类指针或者引用去调用虚函数。

虚函数定义

虚函数重写/覆盖条件 : 函数 + 三同 (函数名、参数、返回值)
不符合重写,就是隐藏关系
特例1: 子类虚函数不加virtual,依旧构成重写(实际最好加上)

特例2:重写的协变。返回值可以不同,要求必须时交子关系的的指针或者引用(极易报错)

为什么呢?明明是father类引用呀。

先说原理

因为对象虚函数表的不同,基类的引用/指针其实指向的是子类的虚表,就好像基类函数给覆盖重写一样。

抛出问题

先写俩类。

class father
{
public:virtual void func1() {printf("father printf\n");}virtual void no_vir(){}protected:const char* _father_val = "fathar";
};class son : public father
{
public:virtual void func1(){printf("son printf\n");}
protected:const char* _son_val = "son";
};

 这究竟是什么原因呢????

探究多态底层

进入调试模式查看father实例化对象parent里有啥。 

_father_val我们知道是成员变量,这_vfptr是什么?

他是一个数组指针指向一个指针数组。这数组保存的是函数地址。这奇奇怪怪的什么情况看看parent的大小

这个二级指针属于这对象中。

看看child对象有什么。

自己_son_vals数据+ 父类继承虚表与父类_father_val.让我们对比一下,parent与child的虚表

 首先vfptr虚表的地址不一样,说明了我们的child与parent对象的虚表是相互独立的,看看各自指向的数组,发现[1]保存的地址数据相同,而[0]的地址数据保存的不同。好关键的来啦

 

将parent对象与child对象都传入test函数。发现调用的函数不同。其实就是应为这的引用与指针调用函数其实是根据虚表的函数地址调用。

画图画图!

 其实所谓的多态其实就是指针或者引用访问的时候派生类中继承基类虚表是,检测自己的函数是否可以重写基类虚函数,可以的话就会改变自己基类中虚表中该函数地址的值,改变为自己函数的地址。


冷门知识

我们的函数替换的时候其实保存的依旧是基类的函数接口。俗话讲:头还在换了个身体。因为在汇编中我们可以知道函数调用call前先需要,将实参压栈(如果写了缺省值就缺省压栈),然后再去调用call函数地址。

运行代码

 重写替换了函数体内代码,但是函数头还是基类的头!!

如果有人这样考你,他一定是一个老六!!

 

 

 


http://www.ppmy.cn/news/313467.html

相关文章

【ROS】郭老二博文之:ROS目录

1、ROS2 【ROS】Ubuntu22.04安装ROS2(Humble Hawksbill) 【ROS】ROS2命令行工具详解 【ROS】ROS2中的概念和名词解释 【ROS】ROS2编程示例:话题订阅-发布-C版 【ROS】ROS2编程示例:服务和客户端-C版 【ROS】ROS2编程示例&#xf…

按钮或图像上的SWIFT UI MacOS弹出窗口

我希望我能做图片中看到的事情。 我正在尝试使用这段代码,但我不太了解怎么修复它。 我希望我可以在Button或ImageMac上使用它,该ImageMac应该是图像。 有人能帮我吗? 编码: func showLittlePopoverWithMessage(sender: NSVie…

模拟电路--单电源差分运算放大电路方案

单电源差分运算放大电路 问题描述实现方案 问题描述 最近要用压电陶瓷做一个有趣的东西,但是压电陶瓷的电压信号有点小,百毫伏级的,所以需要对其进行差分放大。大概浏览了一下主流的差分运算放大电路,基本上都是双电源方案&#…

unity做陶艺(动态改变模型网格)

年后辞职到一家VR开发公司,经理提出要做一个陶艺类课件,类似《一起做陶艺》。当时我就一脸蒙蔽,这怎么做,没有 思路时就先想思路 嗯 这是我的一大优点~ 思路1:把模型横切成若等干份,动态操作每一份的…

4键电子手表说明书_电子手表怎么调(电子手表的四个键的功能各是什么)

展开全部 四个功能键分别是:左上角按键e68a84e8a2ad62616964757a686964616f31333433643062LIGHT,右上角按键ST/SP,左下角按键MODE,右下角按键RESET,具体操作步骤如下: 1、首先,在初始界面中,显示为时间LIGHT,按一次MODE进入秒表,如下图所示,然后进入下一步。 2、其次…

为陶崇园争取正义懒人包1.0

https://media.weibo.cn/article?id2309404228422728593619 此篇文章属于我个人行为,和参与联名的校友无关。 此篇文章属于我个人行为,和参与联名的校友无关。 此篇文章属于我个人行为,和参与联名的校友无关。 昨晚校内匿名信源告诉我涉…

开关电源EMI设计(原理讲解及实战分析)

反激式开关电源EMI设计 EMI滤波器的作用是双方向性的,既能有效阻止外界的电磁干扰经电源线进入设备,又能阻挡设备自身工作中产生的电磁骚扰经电源线进入电网,传送到其他敏感设备。所以它是抗干扰和干扰抑制中都用得到的一种器件。 图中&…

电设——开关电源——LM2596

LM2596是一款比较老的开关电源芯片了,但是架不住比较好用啊,它的电源效率并不算高,但在一般新手级玩家手中差不多能达到75%的电源效率,在此我说说我的理解。 它的外围电路定义的非常简单,5个引脚,采用TO-2…