虚函数表的实现细节

2023-05-16

1.虚函数

·虚表是怎么实现的?虚表存放在哪里?

·虚表中的数据是在什么时候确定的?

·对象中的虚表指针又在什么时候赋值的?

我们很难通过 C++语言本身来找到答案。 C++标准给编译器实现者定义了语法规范,但是被并没有定义如何实现这些语法规范,不同的编译器实现者可能有不同的实现方法,可以肯定的是他们的编译器必须符合这些语法规范。汇编语言作为最接近机器语言的计算机语言,可以为我们揭示一些隐藏在编译器内部的细节。接下来本来就试图通过对 C++源码进行反汇编的方式来解答这些疑惑。

二、分析

这里我选用 WinXP 和 VS2008 作为我们这次分析的平台。我们建立一个最简单的 Win32 控制台程序,并定义两个简单的类:


接下来我们可以直接编译这些 C++源码就可以得到相应的汇编代码。 通过分析这些汇编代码我们就找到许多有用的信息。我们可以找到这样的汇编代码:


以上的汇编代码定义了两个数据段, 而这两个数据段中的内容恰好就是类的虚表。 至此虚表的"庐山真面目"完全展示在我们的面前。 根据这些信息,我们可以推理出很多有用的结论:

·拥有虚函数的类会有一个虚表,而且这个虚表存放在类定义模块的数据段中。模块的数据段通常存放定义在该模块的全局数据和静态数据,这样我们可以把虚表看作是模块的全局数据或者静态数据

·类的虚表会被这个类的所有对象所共享。类的对象可以有很多,但是他们的虚表指针都指向同一个虚表,从这个意义上说,我们可以把虚表简单理解为类的静态数据成员。值得注意的是,虽然虚表是共享的,但是虚表指针并不是,类的每一个对象有一个属于它自己的虚表指针。

·虚表中存放的是虚函数的地址。

另外一个大的疑惑就是对象的虚表指针是在什么时候被赋值的? 我们都知道,类的对象是通过构造函数来完成初始化,但是我们从来没有在构造函数中初始化虚表指针, 那么编译器在幕后又做了哪些事情呢? 我们依然还是通过反汇编来找到答案。 在这个控制台程序的 main 函数中我们构建一个类对象:

 

类的非静态成员函数调用时,编译器会传入一个"隐藏"的参数。 这个参数就是通常我们说的"this"指针,它的值就是对象的地址。 在上面的代码中,寄存器 ECX 保存的就是这个"

this" 指 针 , 同 时 它 的 值 又 赋 给 了 寄 存 器 EAX。"??_7CD-szBase@@6B@"就是上面提到的虚表,同时它也代表了虚表的地址。

接下来,虚表的地址被赋给了由寄存器 EAX 指定的内存中。由此可见,虚表的地址被存放在对象的起始位置,即对象的第一个数据成员就是它的虚表指针。 同时我们还可以注意到,虚表指针的初始化确实发生在构造函数的调用过程中, 但是在执行构造函数体之前,即进入到构造函数的"{"和"}"之前。 为了更好的理解这一问题, 我们可以把构造函数的调用过程细分为两个阶段,即:

1.进入到构造函数体之间。在这个阶段如果存在虚函数的话,虚表指针被初始化。如果存在构造函数的初始化列表的话,初始化列表也会被执行。

2.进入到构造函数体内。这一阶段是我们通常意义上说的构造函数

 

简单的搞个基类Base{void fun();virtual void print(){...};public:int a;static b;}

定义一个对象 B b;调试状态下就可以看到b包含了什么

类中只有虚表指针和普通成员(包括const成员)而普通函数,静态成员是不在类中的.

 





 

 

 

 


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

虚函数表的实现细节 的相关文章

  • STM32 FMC原理详解

    关于FSMC的基本原理已经在这两篇讲解了 xff0c 如果有不懂的建议先看一下 xff0c 这里我们对一些基本概念会说的少一些 xff0c 主要就是针对FMC的特点和FSMC跟FMC的区别做主要的阐述 区别不大 STM32 FSMC FMC
  • 【机器学习】Scikit-learn介绍

    一 Scikit learn简介 Scikit learn是一个支持有监督和无监督学习的开源机器学习库 它还为模型拟合 数据预处理 模型选择和评估以及许多其他实用程序提供了各种工具 二 拟合和预测 xff1a 估算器基础 Fitting a
  • 我的2011--快乐最重要

    呵呵 xff0c 听着郭德纲和于谦老师的相声 xff0c 开始写这篇文章 xff0c 刚毕业不到六个月 xff0c 就换了一份工作 xff0c 很多事情都在意料之外 xff0c 很多事情又在意料之中 xff0c 总之 xff0c 以后回忆到
  • 朱金灿:韧性、悟性、具备快速学习能力是我喜欢的特质

    英雄会是CSDN旗下针对国内IT技术领域专家展示和交流的平台 通过线下线上的互动形式 xff0c 为CSDN社区专家提供更多学习 合作 宣传的机会 英雄会后续将在北上广深等国内一二线城市建立分会 xff0c 各个分会后期将组织技术交流活动
  • 远程连接工具Wind_Term打开远程Linux服务器图形化界面

    我们知道想要在Windows打开Linux图形化程序 xff0c 一个耳熟能详的工具MobaXterm是可以做到的 xff0c 但是不是唯一的工具 xff0c 具有支持X11 转发的工具都是可以实现的 xff0c Wind Term就是这么
  • Error: Failed to load parser ‘babel-eslint‘ declared in

    解决办法 xff1a 使用手动安装 babel eslint npm i D babel eslint
  • 理解依赖注入DI和控制反转IOC和容器

    简介 依赖注入 Dependency Injection 简称 DI xff0c 目的是让代码耦合度降低 xff0c 模块化程度高 xff0c 让代码更易测试 什么是依赖 为什么会有依赖 xff1f 因为我们为了模块化 xff0c 把各种小
  • React生命周期及事件详解

    一 组件的详细说明和生命周期ComponentSpecs and Lifecycle 组件的详细说明 xff08 Component Specifications xff09 当通过调用 React createClass 来创建组件的时候
  • Eclipse代码提示功能失效

    Eclipse 代码提示功能失效问题解决 Windows gt preferences gt java gt Editor gt Code Assist中Auto Activetion中的Enable auto activetion选项要勾
  • VM-tools选项为灰色无法安装的问题

    安装虚拟机VMware时 xff0c 桌面上没有vmware tools的安装光盘 虚拟机 gt 重新安装vmware tools选项为灰色 xff0c 也无法选择 尝试了将CD DVD SATA 的使用ISO映像文件改为物理驱动器 自动检
  • 数据库学习 - like(模糊查询)

    模糊查询问题 比如查询姓张的同学 xff0c 查询张某某等这类型问题 xff0c 在 select语句中通过查询条件中加入运算符 like 来表示 xff1b 含有 like运算符的表达式 列名 not like 字符串 xff08 表示其
  • 蓝桥杯2022年第十三届省赛真题-X进制减法(超详细解析)

    转自作者弗莱 详细解析和分享经验 进制规定了数字在数位上逢几进一 X 进制是一种很神奇的进制 xff0c 因为其每一数位的进制并不固定 xff01 例如说某种 X 进制数 xff0c 最低数位为二进制 xff0c 第二数位为十进制 xff0
  • WearOS复杂数据的刷新

    表盘可以通过setDefaultSystemComplicationProvider int watchFaceComplicationId int systemProvider int type 来设置要显示的系统复杂数据 一 系统支持哪
  • VMware下使用Gparted对系统盘扩容

    第一步 xff0c 下载Gparted的iso镜像文件 xff0c 这里对应下载相应的32或者64位版本 第二步 xff0c 设置虚拟机 xff0c 将硬盘容量扩容为指定的容量 xff0c 保存 第三步 xff0c 设置虚拟机 xff0c
  • Android系统深度游

    项目原因 xff0c 让我们必须深入探索Android系统 xff0c 完成对之前的我们来说比较艰巨的任务 这样 xff0c 我们开启了Android深度游 Android这个系统 xff0c 应用层开发还是比较舒服的 xff0c Goog
  • IT痴汉的工作现状56-耳鸣

    自从这个项目启动 xff0c 与客户方的沟通就逐渐多了起来 xff0c 沟通的方式是语音会议 也不知从什么时候起 xff0c 每天的会议时间变得很长很长 尤其是定位复杂问题时 xff0c 一个会议就要4个小时 张伟是从项目开始买的耳机 xf
  • 我的2020---熬过去

    恰逢周末 xff0c 本人自认为过了一个美好的圣诞节之后 xff0c 在深圳图书馆开始思考我的第十一个年终总结了 提笔之前 xff0c 我翻看了去年的总结 xff0c 想到了我还有一套书没有读完 xff0c 那就是 大败局 2020结束还有
  • 我的2022-工程师文化的思考

    没有想到 xff0c 今年大环境的变化可谓是大开大合 xff0c 超出想象 各行各业都遭到强大的挑战 xff0c 是泯灭还是苟活 xff0c 亦或是再创辉煌 xff0c 时也命也 在此情况下的个人 xff0c 最好的选择是跟公司抱团取暖 x

随机推荐

  • 用户名 不在 sudoers文件中,此事将被报告。

    继续昨天的故事 话说昨天新建了一个帐号linc xff0c 今天在执行sudo时回显一个很吓人的信息 xff1a sudo password for linc linc 不在 sudoers 文件中 此事将被报告 这是要去哪儿报告呢 xff
  • Git冲突:commit your changes or stash them before you can merge.

    今天用git pull来更新代码 xff0c 遇到了下面的问题 xff1a error Your local changes to the following files would be overwritten by merge xxx
  • Android问题集锦之二十八:You need to use a Theme.AppCompat theme (or descendant) with this activity.

    错误描述为 xff1a java lang IllegalStateException You need to use a Theme AppCompat theme or descendant with this activity 起因
  • Docker实践6:Cannot connect to the Docker daemon.

    正在免费适用着Aliyun主机 xff0c 当然要用docker来部署我的服务器啦 但是今天碰到了题目的问题 xff0c 细节如下 xff1a span class hljs comment docker info span FATA sp
  • DFS与BFS总结

    总结 bfs多用于在一次选择中可以有多种情况的选择 而dfs是确定唯一性如唯一路径 xff0c 也就是深度 当问题是全盘式的搜索 xff0c 不在乎形式或者具体情况呈现还是详细过程的 xff0c 使用bfs 当问题是要求具体过程 xff0c
  • 一个简单的自定义通信协议(socket)

    转自 xff1a http vtrtbb javaeye com blog 849336 这是转自javaeye的一篇文章 xff0c 作者是vtrtbb 按照网络通信的传统 xff0c 我们都会自定义协议 xff0c 这有很多好处 xff
  • ImageView 设置图片

    android doc中是这样描述的 xff1a public void setImageResource int resId 这是其中的一个方法 xff0c 参数resld是这样 xff1a ImageView setImageResou
  • Android问题集锦之八:调用其他程序中的activity和Permission Denial: starting Intent 错误解决办法

    今天想调试多个task中栈的情况 xff0c 在测试程序中调用另一个程序的activity xff0c 代码片段如下 xff1a btnStartX 61 Button findViewById R id btnStartX btnStar
  • VB.NET串口通信例子--我的回忆录

    这是我3年前的一个例子 xff0c 最近翻出来回忆一下 串口是计算机上一种非常通用设备通信的协议 大多数计算机包含两个基于RS232的串口 xff0c 现在配电脑好像只有一个 串口同时也是仪器仪表设备通用的通信协议 xff1b 很多GPIB
  • TensorFlowLite GPU加速

    官方文档 https tensorflow google cn lite performance gpu hl 61 zh cn TF LITE支持移动端GPU加速 xff0c 特别对android端的支持比较丰富 相对android来说
  • C语言基础----流程控制

    流程控制是C语言中比较基础的 它分为三种状态 xff1a 1是顺序结构 2是选择结构 3是循环结构 我要说明后两种结构 xff0c 选择机构和循环结构 首先先说 xff1a 选择结构 选择结构是指 xff1a 当一个条件成立则执 xff08
  • 复杂数据类型——数组

    复杂数据类型是C语言基础的重点 1 数组 xff1a 存储一组数据 2 特点 xff1a 只能存放一种类型的数据 如int类型 xff0c float类型的数据 数组的元素个数只可以放常量 int ages 5 61 1 2 3 格式 xf
  • OC语言——基本语法和思想

    今天学习了OC语言基础语法 1 oc语言完全兼容C语言 xff0c 后缀为 m类型 被广泛应运与开发苹果mac os x平台和ios开发平台 2 oc语言关键字基本上以 64 开头 xff0c oc字符串也是以 64 开头 3 基本类型新加
  • OC语言——三大特性-继承与多态

    继承是oc中比较常见的 1 继承 xff1a 就是当两个类拥有相同的属性和方法时 xff0c 就可以将相同的东西抽取到一个父类中 子类可以拥有父类中所有的成员变量和方法 2 继承的好处 xff1a 可以抽取重复代码 xff0c 节省时间 建
  • OC语言——点语法和成员变量的4种作用域及property和synthesize的使用

    点语法 xff1a 点语法的本质还是方法调用 Person p 61 Person new 点语法的本质还是方法调用 p age 61 10 p setAge 10 一 点语法注意点 xff1a 64 implementation Pers
  • 树排序的理解

    参考文献与详细资料 xff1a https blog csdn net weixin 64067830 article details 124443430 视频 https www bilibili com video BV1iU4y1B7
  • OC语言——构造方法和分类的使用

    一 构造方法 1调用 43 alloc分配存储空间 Person p 61 Person alloc 2初始化 init Person p1 61 p init 可以整合为一句 Person p2 61 Person alloc init
  • 使用CSDN-markdown

    欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来 xff0c 用它写博客 xff0c 将会带来全新的体验哦 xff1a Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传
  • 【笔试&面试】关于动态链接库

    动态链接库英文为DLL xff0c 是Dynamic Link Library 的缩写形式 xff0c DLL 是一个包含可由多个程序同时使用的代码和数据的库 xff0c DLL 不是可执行文件 动态链接提供了一种方法 xff0c 使进程可
  • 虚函数表的实现细节

    1 虚函数 虚表是怎么实现的 xff1f 虚表存放在哪里 xff1f 虚表中的数据是在什么时候确定的 xff1f 对象中的虚表指针又在什么时候赋值的 xff1f 我们很难通过 C 43 43 语言本身来找到答案 C 43 43 标准给编译器