总结C++中取成员函数地址的几种方法
来源:互联网 发布:名师讲课软件 编辑:程序博客网 时间:2024/06/14 13:14
这里, 我整理了4种C++中取成员函数地址的方法, 第1,2,4种整理于网上的方法, 第3种cdecl_cast是我自己想到的.
其中, 第4种(汇编)的方法不能在VC6上编译通过. 推荐使用第1,2种方法(pointer_cast 和 union_cast).
至于:为什么要取成员函数的地址? 因为可以通过一定的手段 让成员函数作为回调函数 , 而不再使用全局的静态函数.
天气热,话不多说, 使用方法见最后.
方法1: pointer_cast - 通过静态转换
template<typename dst_type,typename src_type>dst_type pointer_cast(src_type src){ return *static_cast<dst_type*>(static_cast<void*>(&src));}
其实, 我并不明白这个方法为什么成功了, 而且要使用两个static_cast, 一个不行. 而且函数里面使用的&src,
但我传入参数的时候还需要以&ClassName::MemFunc的形式, 不然就是错误的, 为什么?
方法2: union_cast - 通过联合体的共享储存机制
template<typename dst_type,typename src_type>dst_type union_cast(src_type src){ union{ src_type s; dst_type d; }u; u.s = src; return u.d;}
这种方法是最常规, 也是最好理解的一种方法了, 巧妙地利用了联合体的优点. 当然, 模板的使用恰到好处. 同时,传入参数时注意数据类型大小一致.
方法3: cdecl_cast - 通过C语言的可变参数不检测参数类型
__declspec(naked) void* __cdecl cdecl_cast(...){ __asm{ mov eax,dword ptr[esp+4] ret }}
注:在Windows上函数返回值通过eax返回, 所以只需要这么两条汇编语句就行了. 只用于32位平台, 若用于64位, 需要修改一下寄存器.
虽然使用了三个点形式的参数, 但是参数只需传入一个.
方法4: asm_cast - 通过汇编的offset语句取成员函数偏移得到地址
#define asm_cast(var,addr) \{ \ __asm{ \ mov var,offset addr \ } \}
注:这个方法也比较巧妙, 不过貌似在VC6上编译不过. VS2012没问题.
使用方法及测试代码:
#include <iostream>using namespace std;class A{public: void fn(){}};int main(void){ void* p1 = pointer_cast<void*>(&A::fn); void* p2 = union_cast<void*>(&A::fn); void* p3 = cdecl_cast(&A::fn); void* p4 = 0; asm_cast(p4,A::fn); cout<<p1<<endl<<p2<<endl<<p3<<endl<<p4<<endl; return 0;}
0 0
- 总结C++中取成员函数地址的几种方法
- union关键字和取类成员函数地址的方法
- C#string取指定位的几种方法总结
- PHP中打开URL地址的几种方法总结
- c中取地址运算符&与指针取成员运算符->的优先级
- 获取成员方法的地址,将C++类成员方法转换成C自由函数
- 类成员函数作为线程函数的几种方法
- C++中类成员函数作为回调函数的几种方法
- 获取成员函数地址的方法
- [c++]如何取重载函数的地址
- C 语言取整的几种方法
- 获取成员函数地址3种方法
- C++ Template 类成员函数取地址
- C++静态成员函数访问非静态成员的几种方法
- C++静态成员函数访问非静态成员的几种方法
- C++静态成员函数访问非静态成员的几种方法
- C++静态成员函数访问非静态成员的几种方法
- C++静态成员函数访问非静态成员的几种方法
- 关于static
- C++为什么用模板类,为什么用泛型?
- 按钮的可用状态
- JavaScript:事件处理程序
- 我爱机器学习--机器学习方向资料汇总
- 总结C++中取成员函数地址的几种方法
- Java面向对象之内部类
- Android - 源码 - AsyncTask
- Intent的学习
- IOS(sandbox)沙盒和文件操作(NSFileManager)
- Android studio gradle 代码混淆和破解apk
- 表格的处理
- 做网站用UTF-8还是GB2312
- ---JDK中工具类的使用---