回調函數是靜態函數
#include <iostream> using namespace std;class App{public: typedef void(* pClassFun )(void*); static void m_CreateCb(void* user_data) { App *pThis = static_cast<App*>(user_data); 回調函數是非靜態函數#include <iostream>using namespace std;class App{public: typedef void(App::*pClassFun)(void*); static void m_CreateCb(void* user_data) { cout << "m_CreateCb" << endl; } void CreateCb(void * user_data) { cout << "CreateCb" << endl; } void demo(pClassFun func, void * user_data) { (this->*func)(user_data); } void printfFuncAddress() { //error C2276: '&' : illegal Operation on bound member function expression //printf("Function CreateCb address = %p/n", &CreateCb); printf("Function CreateCb address = %p/n", &App::CreateCb); } void begin() { //demo(m_CreateCb, this); demo(&App::CreateCb, this); }};int main(){ App a; a.printfFuncAddress(); a.begin(); return 0;}靜態函數作為回調函數,這種用法很常用。理解C++中非靜態成員方法有點困難,
首先要理解:
->* 指向成員操作的指針 ptr->*ptr_to_member
.* 指向成員操作的指針 obj.*ptr_to_member
->* .* 這兩貨是操作符
對比兩種指針:
#include <iostream>using namespace std;class App{public: typedef void(App::*pClassFun)(void*); typedef void(*pCommonFun)(void*); static void m_CreateCb(void* user_data) { cout << " static m_CreateCb" << endl; } void CreateCb(void * user_data) { cout << "CreateCb" << endl; } void bind(pClassFun classFunc, void * user_data) { m_ClassFunc = classFunc; ClassFuncData = user_data; } void RegisterCallback(pCommonFun commonFunc, void * user_data) { m_CommonFunc = commonFunc; CommonFuncData = user_data; } void Demo() { RegisterCallback(m_CreateCb, this); bind(&App::CreateCb, this); //do something and then trigger callback (this->*m_ClassFunc)(ClassFuncData); m_CommonFunc(CommonFuncData); } void printfFuncAddress() { //error C2276: '&' : illegal operation on bound member function expression //printf("Function CreateCb address = %p/n", &CreateCb); printf("ClassFunc CreateCb address = %p/n", &App::CreateCb); printf("Common static CreateCb address = %p/n", &App::m_CreateCb); }private: pClassFun m_ClassFunc; void *ClassFuncData; pCommonFun m_CommonFunc; void *CommonFuncData;};int main(){ App app; app.printfFuncAddress(); app.Demo(); return 0;}最后我們來看看非靜態函數作為回調函數的應用
sigslot的實現
#include <vector>#include <iostream>using namespace std;template<typename T, typename T1>class slot{public: slot(T* pObj, void (T::*pMemberFunc)(T1)) { m_pObj = pObj; m_pMemberFunc = pMemberFunc; } void Execute(T1 para) { (m_pObj->*m_pMemberFunc)(para); }private: T* m_pObj; void (T::*m_pMemberFunc)(T1);};template<typename T, typename T1>class signal{public: void bind(T* pObj, void (T::*pMemberFunc)(T1 para)) { m_slots.push_back(new slot<T, T1>(pObj, pMemberFunc)); } ~signal() { vector<slot<T, T1>* >::iterator ite = m_slots.begin(); for (; ite != m_slots.end(); ite++) { delete *ite; } } void operator()(T1 para) { vector<slot<T, T1>* >::iterator ite = m_slots.begin(); for (; ite != m_slots.end(); ite++) { (*ite)->Execute(para); } }private: vector<slot<T, T1>* > m_slots;};class receiver{public: void callback1(int a) { cout << "receiver1: " << a << endl; } void callback2(int a) { cout << "receiver2: " << a << endl; }};class sender{public: sender() : m_value(0) {} int get_value() { return m_value; } void set_value(int new_value) { if (new_value != m_value) { m_value = new_value; m_sig(new_value); } } signal<receiver, int> m_sig;private: int m_value;};int main(int argc, char** arg){ receiver r; sender s; s.m_sig.bind(&r, &receiver::callback1); s.m_sig.bind(&r, &receiver::callback2); s.set_value(1); return 0;}新聞熱點
疑難解答
圖片精選