博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何通过函数名获取虚函数的地址?
阅读量:4965 次
发布时间:2019-06-12

本文共 1178 字,大约阅读时间需要 3 分钟。

测试环境:WIN8+VS2012

#include 
#include
using namespace std;class Cbase{public: Cbase() : x(10){} virtual void f(){cout << "Cbase::f" << endl;} virtual void g(){cout << "Cbase::g" << endl;} virtual void h(){cout << "Cbase::h" << endl;}private: int x;};typedef void(*FUN)();typedef void(Cbase::*PFUN)();int main(void){ Cbase a; printf("f = 0%X\n", &Cbase::f); printf("g = 0%X\n", &Cbase::g); printf("h = 0%X\n", &Cbase::h); PFUN c1 = &Cbase::f; PFUN c2 = &Cbase::g; PFUN c3 = &Cbase::h; (a.*c1)(); (a.*c2)(); (a.*c3)(); return 0;}
输出:

既然能够正常输出,我们有理由相信&Cbase::f,&Cbase::g,&Cbase::h,是虚函数表里的地址,事实是这样吗?

有些书上说是获取到虚函数在虚函数表中的索引。但是实际上VS编译器并不是这么做的,获取到的将会是一个用于虚函数调用的地址,这个地址上的指令会先获取虚函数表,然后再通过虚函数表获取虚函数地址相关的项。而GCC的做法又跟VS不同,通过&获取得的值都是1。总而言之,通过取地址&符号获得的不是函数地址,但是可以通过获得的值成功调用该函数。

但在vs中,成员函数指针不是指向函数的真实地址,而是先指向一个位置,该位置会调用Cbase::`vcall'{0}':之后才跳转到真正地址。不同的函数,Cbase::`vcall'{0}':中的数字不同。

本质上还是编译时确定好每个函数的位置,通过此位置来查询虚函数表。

而在VS中,*(int*)*(int*)(&b)也依旧取不到虚函数表地址

可见经过了一次jmp

为什么会jmp,其实和普通函数一样

====================

#include #include 
using namespace std;class Base{public: virtual void Iam() { cout<<"Base::Iam"<

转载于:https://www.cnblogs.com/lgh1992314/p/5834839.html

你可能感兴趣的文章
web项目(用户注册)(web分层结构)
查看>>
Jetty源码学习-编译Jetty源码二三事
查看>>
十种排序
查看>>
让linux开机默认开启小键盘
查看>>
通用登录界面1.1
查看>>
poj 2395 最小生成树
查看>>
工作8年 开个园子
查看>>
并发容器之ConcurrentSkipListSet
查看>>
方法的重载和重写
查看>>
计算机网络 -面经(1)
查看>>
【bzoj5161】最长上升子序列 状压dp+打表
查看>>
RabbitMQ安装
查看>>
dmidecode查看设备硬件信息
查看>>
Day33、基于udp的套接字、socketserver模块、关于进程的简单介绍
查看>>
2.2计算圆柱体的体积.py
查看>>
HDU 3466 Proud Merchants
查看>>
java list 容器的ConcurrentModificationException
查看>>
前端 HTML 注释
查看>>
前端 HTML标签属性
查看>>
glassfish的启动
查看>>