上一文中讲了C语言通过函数指针实现异步回调
本文继续讨论C++中实现回调,由于C++中有类,而C语言中的回调函数不能直接定义为成员函数,所以就很麻烦了,下面将讨论解决办法。
首先知道静态成员函数是全局的,也就是类的,因此推测可以用静态成员函数来实现回调机制。这里补充一下关于类中静态成员的知识
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
class xiabo_C{
public:
xiabo_C():a(10),d(8)
{
printf("I am xiabo_C() function\n");
}
static int sfunc(); //静态成员函数也遵循public,private,protected访问规则
int func(void);
public:
int a;
static int b ; //此处不能初始化
static const int c = 9;//只有静态常量才能直接初始化
const int d;
};
int xiabo_C::b = 11; //静态成员变量的初始化只能这样,不能在构造中初始化
int xiabo_C::sfunc(){ //!!!静态成员函数在类外部实现时,千万不要加static,不要写成了static int sfunc(){},这是内外部的静态C函数
//xiabo::a = 11; //error 静态成员函数不能应用非静态成员
xiabo_C::b = 12;
printf("I am static member function,b = %d\n",xiabo_C::b );
return 0;
}
static int sfunc1(){
printf("I am static function, not member function \n" );
return 0;
}
int xiabo_C::func(void){
xiabo_C::b = 12;
xiabo_C::sfunc();
sfunc1();
return 0;
}
int main(void ){
xiabo_C xiabo;
xiabo.func();
xiabo_C::sfunc(); //静态成员函数是类的,不是某个对象的,引用必须通过类名来访问
getchar();
return 0;
}
下面就使用静态成员函数实现回调,同样的和C语言中一样的结构,只不过改成类
//-------------
class xiabo2_C{
public:
typedef int (*pcb)(int a);
typedef struct parameter{
int a ;
pcb callback;
}parameter;
xiabo2_C():m_a(1){
}
//普通函数
void GetCallBack(parameter* p) // 写回调者实现的回调函数
{
m_a = 2;
//do something
while(1)
{
printf("GetCallBack print! \n");
_sleep(2000);
p->callback(p->a);
}
}
int SetCallBackFun(int a, pcb callback)
{
printf("SetCallBackFun print! \n");
parameter *p = new parameter ;
p->a = 10;
p->callback = callback;
GetCallBack(p);
return 0;
}
public:
int m_a;
};
class xiabo2Test_C{
public:
xiabo2Test_C():m_b(1){
}
static int fCallBack(int a) // 应用者实现的回调函数,静态成员函数,但是不能访问类中非静态成员了,破坏了类的结构
{
//do something
//m_b = a; // 不能访问类中非静态成员了,破坏了类的结构,应用者使用很麻烦
printf("a = %d\n",a);
printf("fCallBack print! \n");
return 0;
}
public:
int m_b;
};
int main(void ){
//test_statichunc();
xiabo2_C xiabo2;
xiabo2.SetCallBackFun(5,xiabo2Test_C::fCallBack);
getchar();
return 0;
}
虽然这种方法实现了回调,但是应用者那是1万个不情愿,尼玛为了用个回调,我类类里面的非静态成员什么都不能用了,还不如不回调呢,让我直接调用吧。那有没有一种方法两全其美呢,有!那是必须的。
//-------------------
template<typename Tobject,typename Tparam>
class xiabo3_C{
typedef void (Tobject::*Cbfun)(Tparam* );
public:
bool Exec(Tparam* pParam);
void Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam);
private:
Cbfun pCbfun;
Tobject* m_pInstance;
};
template<typename Tobject,typename Tparam>
void xiabo3_C<Tobject,Tparam>::Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam){
printf("Set print!\n");
m_pInstance = pInstance;
(pInstance->*pFun)(pParam); //可以直接在这里回调传过来的函数指针
pCbfun = pFun;
}
template<typename Tobject,typename Tparam>
bool xiabo3_C<Tobject,Tparam>::Exec(Tparam* pParam){
printf("Exec print!\n");
(m_pInstance->*pCbfun)(pParam);//也可以在这里回调传过来的函数指针
return true;
}
class xiabo3Test_C{
public:
xiabo3Test_C():m_N(13){
}
void fCallBack(int *p){
printf("fCallBack : Sum = m_N + *p = %d\n",*p + m_N);
printf("fCallBack print! I am a member function! I can access all the member ,HaHa\n");
}
private:
int m_N;
};
int main(void ){
xiabo3_C<xiabo3Test_C,int> xiabo3;
xiabo3Test_C xiabo3Test;
int p = 13;
xiabo3.Set(&xiabo3Test,&xiabo3Test_C::fCallBack,&p); //
xiabo3.Exec(&p);
getchar();
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/xiabodan/article/details/48104149