我在自己上一篇博文《C++类成员函数指针使用实例》中已经写了怎么跨类地使用类成员函数指针的,但,但没有处理成员函数指针里隐含的this指针,所以在被调用的成员函数里使用this指针时,就会让人抓狂,因为this根本无法用。经过一晚上的研究,当然无法避免参考别人的代码,于是将成员函数指针的使用打包成了一个类——事实上也只是保存好this指针与成员函数指针而已,其代码如下:
- #ifndef _Q_CALLBACK_FUNCTION_H_
- #define _Q_CALLBACK_FUNCTION_H_
- //获取类成员函数的地址值
- template<typename TFuncAddr,typename PtrFunc>
- void GetMemberFuncAddr(TFuncAddr& addr, PtrFunc func)
- {
- union
- {
- PtrFunc _func;
- TFuncAddr _addr;
- }ut;
- ut._func = func;
- addr = ut._addr;
- }
- //void (*function)(void) 类型的函数指针
- typedef void (__stdcall * FUNCTION_CALLBACK)(void * This);
- //////////////////////////////////////////////////////////////////////////
- //回调函数类
- class CMemberFunction
- {
- private:
- //类的this指针
- void * _dwPtrThis;
- //成员函数
- FUNCTION_CALLBACK _tagFunc;
- public:
- //添加一个成员函数
- template<typename PtrThis, typename PtrFunc>
- void AddMemberFunction(PtrThis ptrThis, PtrFunc ptrFunc)
- {
- this->_dwPtrThis = (void *)ptrThis;
- DWORD dwAddr = 0;
- GetMemberFuncAddr(dwAddr, ptrFunc);
- this->_tagFunc = (FUNCTION_CALLBACK)dwAddr;
- }
- //调用函数
- void CallMemberFunction(void)
- {
- this->_tagFunc(this->_dwPtrThis);
- }
- };
- #endif //_Q_CALLBACK_FUNCTION_H_
而此类的使用,如下代码:
- class A_Class
- {
- private:
- //回调函数管理类
- CMemberFunction _MemberFuction;
- //其他内容
- //...
- public:
- //模板函数,添加一个回调函数
- //PtrThis 目标类的this指针
- //PtrFunc 目标类的成员函数
- template<typename PtrThis, typename PtrFunc>
- void AddMemberFuction(PtrThis ptrThis, PtrFunc ptrFunc)
- {
- this->_MemberFuction.AddMemberFunction(ptrThis, ptrFunc);
- }
- //调用回调函数
- void CallMemberFunction(void)
- {
- this->_MemberFuction.CallMemberFunction();
- }
- //其他类的内容
- //...
- };
- class B_Class
- {
- private:
- //成员变量
- int num;
- //A_Class类的变量
- A_Class aClass;
- public:
- //被调用的函数
- void __stdcall TestFunction(void)
- {
- this->num++;
- TRACE(_T("%d\r\n"),this->num);
- }
- //本类的初始化
- void Init(void)
- {
- this->num = 0;
- aClass = A_Class();
- aClass.AddMemberFuction(this, &B_Class::TestFunction);
- }
- //调用,也可以在A_Class内部调用
- void Callback(void)
- {
- aClass.CallMemberFunction();
- }
- };
虽然很多人喜欢将示例代码放到main中,但以上是我实际的使用情况,如此一来,被回调的成员函数TestFunction中的this指针就准确无疑了,就不会出现不知指向的情况了,别看代码不多,但真是搞死人的,我承认,俺是低手。
还需要提醒的是,在此我只处理一种调用类型的函数,即
- //void (*function)(void) 类型的函数指针
- typedef void (__stdcall * FUNCTION_CALLBACK)(void * This);
__stdcall还有__thiscall是VC中两中不同的函数调用方式,其具体内涵我还没时间深入了解,以后再说吧。然后,我这里的成员函数是不带参数的,如果需要带参数就请参考我的上一篇文章里提供的连接吧,以上我用的是VS2008。
最后吐槽一下,搞这个问题搞到凌晨3点,码农真TMD伤不起啊!!!!