直接获取类中(非static)成员函数地址的方法
来源:互联网 发布:显卡优化怎么设置 编辑:程序博客网 时间:2024/06/17 13:03
类中的静态成员函数,和非类中的普通函数,函数名即为函数地址:
#include<iostream>using namespace std;class A{public:void fun1(){}static void fun2(){}};void fun3(){}int main(){cout << &A::fun1 << '\t' << A::fun2 << '\t' << fun3 << endl; }
输出为:1 010D1226 010D1249
可以看到后面两个是函数地址,而fun1却是1,而且fun1需要取地址符号&,否则编译不通过:
'A::fun1': function call missing argument list; use '&A::fun1' to create a pointer to member,编译器不认为A::fun1是一个函数(地址),我单步调试到<ostream>中查看源码,但是f11进去1就已经输出了,这个1是怎么输出出来的,有待研究,知道的人望留言告知。
试了一下用
printf("%p\n", &A::fun1);
能输出地址。这里不纠结了。
既然能直接输出地址,那么就能用普通的函数指针操作类中的成员函数:
#include<iostream>#include<sstream>using namespace std;int trans(string str){stringstream os;os << str;os.flags(os.hex);int temp;os >> temp;return temp;}class A{public:void fun1(){ cout << "fun1 call" << endl; }static void fun2(){}};void fun3(){}typedef void(*P)();int main(){char buf[9];sprintf(buf,"%p", &A::fun1);P pr = (P)trans(string(buf, buf + 8));pr();}
另外附上完整的测试代码(包含用类对象来调用普通成员函数的地址):
#include<iostream>#include<sstream>using namespace std;int trans(string str){stringstream os;os << str;os.flags(os.hex);int temp;os >> temp;return temp;}class A{public:void fun(){cout << "A::fun call" << endl;}static void fun2(){cout << "fun2(static) call" << endl;}};void fun1(){cout << "fun1 call" << endl;}typedef void( A::*p_void_class)();//__thiscalltypedef void(*P_void_normal)();//normalint main(){A a;p_void_class p = &A::fun;char temp[9];sprintf(temp,"%p", p);cout << (void*)trans(string(temp, temp + 8)) << endl;P_void_normal adrr = (P_void_normal)trans(string(temp, temp + 8));//将p转化为普通指针cout << adrr << endl;printf("%p\n", p);//调用printf能输出 __thiscall 函数指针P_void_normal p1 = fun1;P_void_normal p2 = A::fun2;adrr();//调用fun(a.*p)();//调用fun,用对象来调用p1();//调用fun1p2();//调用fun2return 0;}后来我看到一个“奇怪”的现象,new一个对象的指针,将其delete后,该指针任然能访问其成员函数
A* p = new A;delete p;p->fun1();
这是为何?想了一下想明白了,就算执行p=NULL或者delete p;p的类型不会改变,仅仅是把对象的数据成员占据的内存释放了。既然是A*的类型,当然能访问A里面的成员函数,就像下面这样
//int x=rand();char x='a';((A*)x)->fun1();
不管x是什么东西,字符也好,随机整数也好,只要是能转化成指针类型的都能访问fun1();
这也充分说明类中普通成员函数(有虚函数时只是多了个虚表)和类对象是分离的。所有的类对象访问的是同样的成员函数,和类外的普通函数没什么区别。一个类对象的指针访问成员函数时,该指针的值已经没有任何意义,编译器能直接根据类型找到函数的入口地址。至于如何得到类中成员函数的入口地址,前面已经讲过方法,不再赘述。
0 0
- 直接获取类中(非static)成员函数地址的方法
- 获取成员函数地址的方法
- 获取类成员函数地址和调用的方法
- C++中static成员函数访问非static成员变量
- C++中static成员函数访问非static成员变量
- 获取成员方法的地址,将C++类成员方法转换成C自由函数
- java中static特殊性和final(static成员直接被访问,this不能用在static方法中,static不可访问非static)
- 关于C++类中静态函数无法直接访问非静态成员的理解
- 获取类成员方法的地址
- static成员函数访问非static成员
- 类的static函数实现非static成员函数作窗口过程函数
- 直接调用类成员函数地址
- 直接调用类成员函数地址
- 直接调用类成员函数地址
- 直接调用类成员函数地址
- 直接调用类成员函数地址
- 直接调用类成员函数地址
- [转载]直接调用类成员函数地址
- hibernate配置C3P0连接池
- NYOJ 题目745 蚂蚁的难题(二)(dp)
- 第一个Windows窗体程序
- php获取汉字字符串长度
- Hive - 简介
- 直接获取类中(非static)成员函数地址的方法
- 平衡二叉树详解
- 百度笔试题,求数组最大数,该数为数组中某两个数相加
- jdbc+连接池
- 快速排序算法C++
- 创新资讯平台整理
- c语言基本编程复习
- 对sqlite的微型数据库的认知
- mySQL中replace的用法