`
qimo601
  • 浏览: 3415707 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

C++ 实现把非静态成员函数作为回调函数(非static)

阅读更多
众所周知,C++的类成员函数不能像普通函数那样用于回调,因为每个成员函数都需要有一个对象实例去调用它。

        通常情况下,要实现成员函数作为回调函数,一种常用的方法就是把该成员函数设计为静态成员函数,但这样做有一个缺点,就是会破坏类的结构性,因为静态成员函数只能访问该类的静态成员变量和静态成员函数,不能访问非静态的,要解决这个问题,需要把对象实例的指针或引用做为参数传给它。

        在一次偶然的机会下,看到了一种方法可以简单的实现回调非静态成员函数,其原理就是把要调用该成员函数的对象实例赋值给一个变量,然后通过该变量来调用成员函数。把逻辑整理了一下,然后写了一个简单的回调代理类,通过这个类,可以简单的实现非静态函数的回调。

 

CallbackProxy.h
 
#ifndef __CALLBACK_PROXY_H__ 
#define __CALLBACK_PROXY_H__  
  
//Tobject:调用对象的类型,Tparam回调函数参数的类型  
template<typename Tobject, typename Tparam>  
class CCallbackProxy  
{  
    typedef void (Tobject::*CbFun)(Tparam*);  
  
public:  
    void Set(Tobject *pInstance, CbFun pFun);  
    bool Exec(Tparam* pParam);  
  
private:      
    CbFun       pCbFun;     //回调函数指针  
    Tobject*    m_pInstance;    //调用对象  
};  
  
//设置调用对象及其回调函数  
template<typename Tobject, typename Tparam>  
void CCallbackProxy<Tobject, Tparam>::Set(Tobject *pInstance , CbFun pFun)  
{  
    m_pInstance = pInstance;   
    pCbFun = pFun;  
};  
  
//调用回调函数  
template<typename Tobject, typename Tparam>  
bool CCallbackProxy<Tobject, Tparam>::Exec(Tparam* pParam)  
{  
    (m_pInstance->*pCbFun)(pParam);  
    return true;  
}  
  
#endif  

 下面演示下如何使用该类

 
test.cpp
#include "CallbackProxy.h"  
  
class CTest  
{  
public:  
    CTest(int nNum);  
    void CbPrintSum(int *pnAddNum){printf("The Sum is %d\n", m_nSum+*pnAddNum);};  
  
private:  
    int m_nSum;  
};  
  
int main(int argc,  char* argv[])  
{  
    CCallbackProxy<CTest, int> CbProxy;  
  
    CTest TestInstance(20);  
  
    CbProxy.Set(&TestInstance, &CTest::CbPrintSum);  
  
    int nNum = 1000;  
    CbProxy.Exec(&nNum);  
  
    return 0;  
}  
  
CTest::CTest(int nNum):  
m_nSum(nNum)  
{  
  
}  
 
分享到:
评论

相关推荐

    Visual C++2010开发权威指南(共三部分).part1.rar

    5.4.3 回调项和回调屏蔽 200 5.4.4 创建列表控件 200 5.4.5 创建图像列表 201 5.4.6 向控件添加列(报表视图) 204 5.4.7 向控件添加项 205 5.4.8 在列表控件中滚动、排列、排序和查找 205 5.4.9 在列表控件中实现...

    传智播客扫地僧视频讲义源码

    26_静态成员变量和静态成员函数 27_C++面向对象模型初探_传智扫地僧 28_this指针 29_作业 源码及文档 01_上一次课程回顾 02_const修饰的是谁_传智扫地僧 03_this的const修饰课堂答疑 04_全局函数pk成员函数(返回...

    Linux多线程服务端编程:使用muduo C++网络库

    1.11.2弱回调. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 24 1.12替代方案. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 26 1.13心得与小结. . . . . . . . . . ...

    VC++2010权威开发指南+源代码

     1.8.3 静态断言static_assert 17  1.8.4 auto关键字 18  1.8.5 右值引用 19  1.8.6 安全数据类型 22  1.8.7 移动构造 23  1.9 支持开发并行程序 26  1.9.1 运行库支持native代码 26  1.9.2 调试和分析工具 ...

    VC++2010权威开发指南+源代码.part2

     1.8.3 静态断言static_assert 17  1.8.4 auto关键字 18  1.8.5 右值引用 19  1.8.6 安全数据类型 22  1.8.7 移动构造 23  1.9 支持开发并行程序 26  1.9.1 运行库支持native代码 26  1.9.2 调试和分析工具 ...

    java 面试题 总结

    接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象...

    c#学习笔记.txt

    可以在方法中更改该值,但当控制传递回调用过程时,不会保留更改的值。通过使用方法参数关键字,可以更改这种行为。如果没有ref,out则默认为值传递,虽然可以在方法中修改这个参数的值,但是修改后的值不会还会到调用...

    超级有影响力霸气的Java面试题大全文档

    接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象...

    易语言程序免安装版下载

     支持静态链接其它编程语言(如C/C++、汇编等)编译生成的静态库(.LIB或.OBJ),但仅限于COFF格式,支持cdecl和stdcall两种函数调用约定。  使用说明如下:函数声明和调用方法与DLL命令一致;“库文件名”以.lib...

Global site tag (gtag.js) - Google Analytics