C++ 實現把非靜態成員函數作為回調函數(非static)(轉)


 
  345人閱讀  評論(0)  收藏  舉報

        眾所周知,C++的類成員函數不能像普通函數那樣用於回調,因為每個成員函數都需要有一個對象實例去調用它。

        通常情況下,要實現成員函數作為回調函數,一種常用的方法就是把該成員函數設計為靜態成員函數,但這樣做有一個缺點,就是會破壞類的結構性,因為靜態成員函數只能訪問該類的靜態成員變量和靜態成員函數,不能訪問非靜態的,要解決這個問題,需要把對象實例的指針或引用做為參數傳給它。

        在一次偶然的機會下,看到了一種方法可以簡單的實現回調非靜態成員函數,其原理就是把要調用該成員函數的對象實例賦值給一個變量,然后通過該變量來調用成員函數。把邏輯整理了一下,然后寫了一個簡單的回調代理類,通過這個類,可以簡單的實現非靜態函數的回調。

 

CallbackProxy.h

 

[cpp]  view plain copy
  1. #ifndef __CALLBACK_PROXY_H__  
  2. #define __CALLBACK_PROXY_H__  
  3.   
  4. //Tobject:調用對象的類型,Tparam回調函數參數的類型  
  5. template<typename Tobject, typename Tparam>  
  6. class CCallbackProxy  
  7. {  
  8.     typedef void (Tobject::*CbFun)(Tparam*);  
  9.   
  10. public:  
  11.     void Set(Tobject *pInstance, CbFun pFun);  
  12.     bool Exec(Tparam* pParam);  
  13.   
  14. private:      
  15.     CbFun       pCbFun;     //回調函數指針  
  16.     Tobject*    m_pInstance;    //調用對象  
  17. };  
  18.   
  19. //設置調用對象及其回調函數  
  20. template<typename Tobject, typename Tparam>  
  21. void CCallbackProxy<Tobject, Tparam>::Set(Tobject *pInstance , CbFun pFun)  
  22. {  
  23.     m_pInstance = pInstance;   
  24.     pCbFun = pFun;  
  25. };  
  26.   
  27. //調用回調函數  
  28. template<typename Tobject, typename Tparam>  
  29. bool CCallbackProxy<Tobject, Tparam>::Exec(Tparam* pParam)  
  30. {  
  31.     (m_pInstance->*pCbFun)(pParam);  
  32.     return true;  
  33. }  
  34.   
  35. #endif  


 

下面演示下如何使用該類
 
test.cpp
[cpp]  view plain copy
  1. #include "CallbackProxy.h"  
  2.   
  3. class CTest  
  4. {  
  5. public:  
  6.     CTest(int nNum);  
  7.     void CbPrintSum(int *pnAddNum){printf("The Sum is %d\n", m_nSum+*pnAddNum);};  
  8.   
  9. private:  
  10.     int m_nSum;  
  11. };  
  12.   
  13. int main(int argc,  char* argv[])  
  14. {  
  15.     CCallbackProxy<CTest, int> CbProxy;  
  16.   
  17.     CTest TestInstance(20);  
  18.   
  19.     CbProxy.Set(&TestInstance, &CTest::CbPrintSum);  
  20.   
  21.     int nNum = 1000;  
  22.     CbProxy.Exec(&nNum);  
  23.   
  24.     return 0;  
  25. }  
  26.   
  27. CTest::CTest(int nNum):  
  28. m_nSum(nNum)  
  29. {  
  30.   
  31. }  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM