反汇编之C++的虚函数
发布日期:2021-05-26 20:04:55
浏览次数:9
分类:技术文章
本文共 1391 字,大约阅读时间需要 4 分钟。
先来查看一简单例子
#include<iostream>
using namespace std;
class Base{
public:
virtual void f() { cout << "base f()被call"<<endl; }
virtual void g() { cout << "父类虚函数G被call" << endl; }
};
class Derive : public Base{
public:
virtual void f() { cout << "子类虚函数f()被call" << endl; }
};
int main()
{
Derive d; //子类对象
Base *pb;//父类指针
pb = &d;//父类指针指向子类对象
int *q =(int*) pb;//取出类对象地址
void(*f)(Derive*) = (void(*)(Derive*))(*(int*)(*q));//取出f()函数地址
void(*g)(Derive*) = (void(*)(Derive*))(*(int*)(*q+4));//取出g()函数地址
f((Derive*)pb);//调用子对象虚函数表的第一个元素
g((Derive*)pb);//调用子对象虚函数表的第二个元素
system("pause");
return 0;
}
用VS2015调试一番.查看pb保存子对象的地址.
以上pb保存了子类对象的地址,地址为0x003bfb64.来看看.这个子类对象的首4个字节(32位机子)地址保存了啥内容(其实是虚函数表的地址)
.
子类对象首4个字节保存了00948b34这个数值.(这个其实是虚函数表的地址).再来看看这个数值保存了啥内容.
发现这个地址开始 0094142e跟00941424应该就是虚函数的地址了.不信.咋们到反汇编查看该地址内容.
先查看0x0094142e(函数转为反汇编.其实第一个地址就是跳转).发现没.反汇编已经提示了是Derive::f这个函数
再看看0x00941424.是Base::g这个函数
以上可知.一般编译器实现.把虚函数表的地址用放在子对象首4个字节.虚函数表保存的是虚函数的地址.
void(*f)(Derive*) = (void(*)(Derive*))(*(int*)(*q));//取出f()函数地址
void(*g)(Derive*) = (void(*)(Derive*))(*(int*)(*q+4));//取出g()函数地
比如以上2行.q是子对象的地址.(*q)就是虚函数表的地址 (*q)+4 相当于虚函数的第二个元素的地址. *(int*)(*q)表示第一个虚函数的地址.*(int*)(*q+4));表示第二个虚函数表的地址..最后强制转换为类成员函数.用(void(*)(Derive*).因为一般类成员函数在编译后.首形参是一个this指针.这里用Derive*.因为this指针的类型就是类的类型
f((Derive*)pb);//调用子对象虚函数表的第一个元素
g((Derive*)pb);//调用子对象虚函数表的第二个元素
最后调用这2个虚函数表中的虚函数.把pb(子对象的地址)当做参数this指针.然后直接调用.即可使得函数被调用了
转自
转载地址:https://blog.csdn.net/Gaodes/article/details/81701958 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月11日 05时14分47秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Unity中获取物体的尺寸(size)的三种方法
2019-04-27
Unity中的关节组件和绳子效果的实现
2019-04-27
Unity可视化编程插件: Bolt,可以像UE4的蓝图那样啦
2019-04-27
Android的.dex、.odex与.oat文件扫盲
2019-04-27
Unity移动应用如何在Bugly上查看崩溃堆栈
2019-04-27
unity3D 在屏幕边框创建碰撞框
2019-04-27
xml中常用的转义符
2019-04-27
关于MSDK的几个难点
2019-04-27
使用UnityEditor做工具
2019-04-27
Visual Studio我常用的快捷键
2019-04-27
写C# dll供Unity调用
2019-04-27
Linux制作run安装包
2019-04-27
一分钟学会C#解析XML
2019-04-27
unity AssetBundle的资源管理
2019-04-27
【转】Unity中HideInInspector和SerializeField一起使用
2019-04-27
单例模板类
2019-04-27
Unity与java相互调用
2019-04-27
android截屏代码
2019-04-27
unity NGUI图文混排
2019-04-27