离多态更近一步

news2024/10/9 14:20:57

在面向对象的语言里面,封装,继承,多态可谓是在熟悉不过了,当我们每次再去重新认识它们的时候总会有新的发现,为此我也经常感到疑惑,所以在这里和大家一起探讨三个问题,让我们在向多态靠近一点点。

虚表是否真的存在静态区

经常我们都会看见一个问题,虚表到底是存放在哪里的。当我们去往上查阅的时候都能出奇的发现一个答案,虚表是存放在静态区中的。对此我曾感到疑惑,存放数据的地方无非有栈,堆,静态区,常量区,首先我们可以排除堆区,因为系统不会自己去开一块空间来使用。接下来我们先了解一下虚表的存放体制,当一个对象在局部域中被创建出来并且它其中也有一张虚表,当局部对象被销毁后在另一个域类定义同一个对象,会发现它们使用的是同一张虚表。

 那么现在还剩下栈区,常量区,静态区,我们可以想一下如果虚表是存放在main函数里面的,那么也是符合条件的,同样,常量区和静态区更不用说。对此我们知道一个观念,相同的数据往往它们存放的地址不会太远,那么我们可以利用这一特征来检验一下看虚表离谁的地址比较近。

  通过这样一段代码我们可以清楚的看到,虚表的地址似乎离静态区相隔很远,但是离常量区似乎很近,那么我们是不是能得出,其实虚表是存放在常量区而并非静态区呢。

派生类中没被重写的虚表去哪里了

首先我们看这样一段代码

 基类中有一个fun1和fun2的虚函数,而派生类有两个不是重写的虚函数

 当我们想去虚表里面找到这个fun3和fun4的时候发现这两个函数并没有在虚表里面,那么问题来了,它们去哪里了呢。我们对此进行更深一步的研究,通过这个虚表去内存里面看看是否能找到消失的它。

 通过对比我们似乎还真找到了这两个地址,但是怎么证明这两个地址就是我们要找的小时的那两个函数呢。

对此我们在回过头来先在了解一下什么是虚函数表。简称虚表,它是由一个指针指向一块空间,空间里面存放了一些地址相连的值,并且这个地址是一个指向函数的指针。那么我们可不可以以认为虚表实际上是一个函数指针数组呢。

 既然这样我们就可以用一个函数指针来取出虚表里面的指针,然后通过这个指针去找到那个函数,对此可以先在函数里面添加一点用于标识的东西。

 我们用这样一段代码来证明我们的猜想。

 通过验证确实得出,那两个地址就是我们消失的fun3和fun4,这就说明,其实并不是不是重写的函数消失了,而是编译器通过特别的方式把它隐藏了起来。

多继承中被重写的虚函数会被放在哪个基类

假设由这样一段代码,一个子类继承成两个父类,那么在子类中,没有被重写的那个虚函数会被放在父类里面呢。

 最好的办法就是去实践它,我们去运行这段代码就会发现,实际上没有被重写的虚函数会被放在base1类里面

 但是我们似乎发现了一个不一样的点,同样是派生类对象D去调用的fun1,为什么调用的地址是不一样的呢。

我们先设置两个基类指针去指向派生类的对象, 然后通过反汇编去看一下具体是什么原因。先通过监视窗口去观察base1的虚函数表是个怎么样的

 可以看到,base1里面第一个第一个虚函地址为0x003f103c,然后主要看反汇编去调用这个函数的那句指令

 看到的是call了这个eax,那么我们再去看一下这个eax是一个什么

 可以看到eax和虚函数表里面第一个地址是一样的,就说明是找到了第一个函数,接下来就要开始调用了,我们按F11(逐语句调试)继续往下一步走

通过这个地址我们找到了fun1,继续往后走

 通过jmp我们拿到了fun1的真正的地址,最后我们得出结论,base1中的调用是正常的,接下来我们继续看看base2的调用

 通过base2同样来到了call这个地址

 eax同样和第一个虚函数同样的,到目前一切为止一切正常,我们继续往下走

同样的是一句jmp,继续往下走 

 来到这里我们就发现这里和上面不一样,当继续jmp的时候它并没有去到fun1的真正地址,而是执行了sub对ecx(*this指针)减去4,实际上是对*this指针减去了4。我们继续往下走

 当我们来到这里就会发现,这个地址好像就是在对base1进行fun1调用的时候出现的地址

 来到这一步我们才发现,最终base2也是调到了fun1但是它饶了一大圈。那么问题又来了,为什么base1不需要绕一大圈呢,这里咱们可以画个图理解一下

首先我们要知道我们要调的是derive的fun1,那么要调derive的fun1就要让指针指向derive对象,base1不用进行操作时因为derive恰好指向derive的开始,而base2却不是,所以要对它进行-4让它指向derive之后才真正开始调用fun1。

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

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

相关文章

使用show effective grants查看权限

1、问题描述 用户 show grants 显示只有连接权限,但该用户却能执行 sbtest.*下的所有操作 GreatSQL> \s ... Server version: 8.0.32-24 GreatSQL, Release 24, Revision 3714067bc8c ... GreatSQL> show grants; ---------------------------------------…

哪些在线工具能免费转换MP3格式?分享两个方法!

哪些在线工具能免费转换MP3格式?通常来说,MP3格式转换器都具备简洁的界面、便捷的操作以及强大的功能,它们可以将各种流行的视频或音频格式转换成MP3文件,甚至可以制作手机铃声。用户只需要在设置中设定录制时间,即可轻…

MIT 6.830数据库系统 -- lab four

MIT 6.830数据库系统 -- lab four 项目拉取引言事务、锁 & 并发控制事务ACID特性两阶段锁 Recovery and Buffer ManagementGranting Locks(授予锁)练习1 Lock Lifetime练习2 Implementing NO STEAL练习3 事务练习4 死锁和中止练习5 项目拉取 原项目使用ant进行项目构建&am…

勘探开发人工智能应用:初至波拾取

AI在油田主营业务即勘探开发运销和经营管理领域的落地场景,需要的算法、模型及关键技术。 1 初至波拾取 在地震数据采集过程中,由人工震源激发后检波器最先接收到地震波的起跳位置,得到这一位置的过程就是初至拾取。“初至拾取在构建精细近…

AI生成写真照 妙鸭能取代海马体?

只要9.9元和21张照片,就能生成各种风格的个人写真照,界面简洁、卖点吸睛的妙鸭相机突然火了。采用AI技术,它以更低的成本和更高的效率,让用户足不出户“拍写真”,有人直呼,它要抢海马体这类实体照相馆的饭碗…

基于51单片机和proteus的模拟楼道灯系统

此系统是基于51单片机和proteus的仿真设计,功能如下: 1. 系统实时检测楼道光照强度。 2. 光照弱情况下,触摸或声音可开启楼道灯。 3. 光照强情况下,触摸或声音都不能开启楼道灯。 4. 楼道灯开启一段时间(3S&#x…

数据库应用:MySQL MHA高可用集群

目录 一、理论 1.MHA 2.MySQL MHA部署准备 3.MySQL MHA部署 二、实验 1.MHA部署 三、问题 1.中英文符兼容报错 2.MHA测试 ssh 无密码认证语法报错 3.MHA测试 ssh 无密码认证log-bin报错 4.MHA测试 mysql 主从连接情况报错slave replication 5.MHA测试 mysql 主从连…

高质量代码究竟依赖设计还是重构而来?

👉导读 一个有所追求的程序员一定都希望自己能够写出高质量的代码,但高质量代码从何而来呢?有人认为是设计出来的,就像一栋稳固的大厦,如果没有前期优秀的设计那么肯定难逃豆腐渣工程的命运;也有人认为是重…

什么是NQA?

一、什么是NQA? 网络质量分析NQA(Network Quality Analysis)是一种实时的网络性能探测和统计技术,可以对响应时间、网络抖动、丢包率等网络指标进行统计。NQA能够实时监视网络服务质量,在网络发生故障时进行有效的故障…

年内实现全面自动驾驶?快来恶补一下自动驾驶技术吧

在7月6日召开的2023世界人工智能大会上,特斯拉CEO斯克预测,随着人工智能技术的快速发展,大约在今年年末,就会实现全面自动驾驶。 他说,“我之前也做过许多类似的预测,我承认之前的预测也不完全准确&#x…

《中国大学生计算机设计大赛》应用与开发组 “国二省一“ 备赛心得,万字干货 (建议收藏)

💧 《中国大学生计算机设计大赛》备赛心得 \color{#FF1493}{《中国大学生计算机设计大赛》备赛心得} 《中国大学生计算机设计大赛》备赛心得💧 🌷 仰望天空,妳我亦是行人.✨ 🦄 个人主页——微风撞见云的博客…

Python编译过程和执行原理

hello,这里是Token_w的文章,主要讲解python的基础学习,希望对大家有所帮助 整理不易,感觉还不错的可以点赞收藏评论支持,感谢! 目录 一. Python执行原理二. Python内部执行过程2.1 编译过程概述2.2 过程图解…

8.6 PowerBI系列之DAX函数专题-非日期类型的累计聚合

需求 需求1: 需求2: 实现 1.需求1实现: (1)在power query中添加列-添加索引列; (2)根据索引列进行累加计算。 度量值 累计聚合销售额 var current_pro_type selectedvalue(…

iTOP-RK3588开发板编译Buildroot

Buildroot 是一款集成的编译集合包,解决了以前交叉编译麻烦的问题,本小节将介绍 buildroot 镜像的编译流程,分为单独编译和完整全自动编译。 首先输入以下命令,选择 buildroot 系统的配置文件 source buildroot/build/envsetup…

办公楼管理高手:一起来学烟雾监测实用技能!

在现代社会中,安全意识和防患意识越来越受到重视。特别是在大型办公楼等人员密集的场所,火灾的风险不容忽视。 为了保障员工和资产的安全,烟感监控成为一项至关重要的安全措施。烟感监控系统作为火灾预警的关键组成部分,能够及早发…

Ubuntu18.04未安装Qt报qt.qpa.plugin could not load the Qt platform plugin xcb问题的解决方法

在Ubuntu 18.04开发机上安装了Qt 5.14.2,当将其可执行程序拷贝到另一台未安装Qt的Ubuntu 18.04上报错:拷贝可执行程序前,使用ldd将此执行程序依赖的动态库也一起拷贝过去,包括Qt5.14.2/5.14.2/gcc_64/plugins目录系的platforms目录…

实现基于UDP简易的英汉词典

文章目录 实现目标认识相关接口socketbzerobindrecvfromsendto 实现思路和注意事项完整代码Server.hppServer.ccClient.hppClient.cc 运行效果END 实现目标 实现一个服务端和一个客户端,客户端负责发送一个单词,服务端接收到后将翻译后的结果返回发送到…

学术研究 #可视化工具 #学术文献绘图 #研究利器 #Citespace #vosviewer

目录 专题一 文献计量学方法与应用简介 专题二 主题确定、检索与数据采集 专题三 VOSviewer可视化绘图精讲 专题四 Citespace可视化绘图精讲 专题五 R语言文献计量学绘图分析 专题六 论文写作 专题七 论文投稿 文献计量学是指用数学和统计学的方法,定量地分析…

Jmeter接口/性能测试,Jmeter使用教程(超细整理)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、线程组 线程组…

数据结构的复杂度

> 作者简介:დ旧言~,目前大一,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 望小伙伴们点赞👍收藏✨加关注哟💕&#x1…