您的位置:首页 > 编程语言 > C语言/C++

C++的回调函数的简单实现

2017-04-10 10:32 288 查看
在网络消息处理中经常要用到回调机制,有的是来处理异步网络数据通信问题(摄器模式),有的是来处理订阅问题(观察者模式)。

在C/C++开发用用的很多,一下是一些简单的例子(部分例子代码不全,需自行补全)

一、C的回调函数是比较简单的,

例如: 

int myFunction(int num)

{
printf("myFunction num:%d\n",num);
return -1;

}

//定义FUNC类型是一个指向函数的指针

//params[in]为int类型

//return为int类型

typedef int (*FUNC)(int);

int _tmain(int argc, _TCHAR* argv[])

{
FUNC callback = (FUNC)&myFunction;
int num = 10;
callback(10);
return 0;

}

执行结果:myFunction num:10

二、对于C++来说如何实现回调函数呢?

1、最原始的方法我们可以在类外定义全局的函数实现回调,参数上通过传递this指针来达到处理当前对象的一些业务。

例如:

typedef bool (*FUNC1)(void* pCFunc);

bool onGetFunName(void* pCFunc)

{
if(pCFunc != NULL)
{
CFunc* fuc = (CFunc*)pCFunc;
bool ret = fuc->getName();
printf("name is:%d\n", ret);
return true;
}
return false;

}

CFunc::CFunc(void)

{

}

CFunc::~CFunc(void)

{

}

bool CFunc::getName()

{
printf("getName ");
return true;

}

bool CFunc::showName()

{
FUNC1 callback = (FUNC1)&onGetFunName;
return onGetFunName(this);

}

执行结果:getName name is:1

2、一般来说我们更想让对象之前共享一个回调函数,所以很多时候用类函数来实现回调函数,例如我们一个简单的线程测试类:

//***************************************************************//

class MyThread

{

public:
MyThread(void);
~MyThread(void);

int init();

int destory();

//定义成static的类函数,此时类函数里无法操作对象私有变量
static void* __stdcall threadBody(void* arg);
static void* __stdcall producer(void* arg);

int creatProduct();
int creatConsumer();

};

/************************************************************/

static hpr_sem g_Semaphore(0);

static hpr_mutex g_mutex;

static TaskQueMgr g_MsgQ;

MyThread::MyThread(void)

{

}

MyThread::~MyThread(void)

{

}

int MyThread::init()

{
return 0;

}

int MyThread::destory()

{
//线程结束
HPR_Thread_Exit();
return 0;

}

void* __stdcall MyThread::threadBody(void* arg)

{
//hpr_guard<hpr_mutex> m_guard(g_mutex);
int nThreadnum=*(int*)arg;

//线程挂起等待
g_Semaphore.wait();

printf("creat thread :%d true\n", nThreadnum);
if(g_MsgQ.QueryTaskNum() != 0)
{
TASKEVENT* task = g_MsgQ.PopFirstTask();
if(task == NULL)
{
printf("get task error\n");
return ((void *)0);
}

int type = task->iMsgType;
int iPriority = task->iPriority;
std::vector<int> *vec = task->iDataVec;

printf("type:%d\n", type);

if(vec != NULL)
{
for(UINT32 j=0; j<vec->size(); ++j)
{
printf("data:%d\n", vec->at(j));
}
}
}
return ((void *)0);

}

void* __stdcall MyThread::producer(void* arg)

{
//线程类实例,暂时无用
MyThread*mThread = (MyThread*)arg;
printf("creat thread producer true\n");
TASKEVENT* task = new TASKEVENT;
std::vector<int> *vec = new std::vector<int>();
for(int i=0;i<10; ++i)
vec->push_back(i);
task->iMsgType = 1;
task->iPriority = 0;
task->iDataVec = vec;
g_MsgQ.PushTask(task);

//通知处理线程
g_Semaphore.post(1);

return ((void *)0);

}

int MyThread::creatProduct()

{
//创建生产者线程
HPR_HANDLE proHandle;

proHandle = MY_Thread_Create(MyThread::producer, this, 0);
if( proHandle == NULL)
{
SH_ERROR("creat thread proHandle failed!!\n");
return -1;
}
return 0;

}

int MyThread::creatConsumer()

{
HPR_HANDLE ret[THREAD_NUM_C];

for(int i=0; i<THREAD_NUM_C; ++i)
{
ret[i] = MY_Thread_Create(MyThread::threadBody, &i, 0);
if( ret[i] == NULL)
{
SH_ERROR("creat thread %d failed!!\n", i);
}
}
//g_Semaphore.post_1();
return 0;

}

main()

//**********************************//
MyThread myThread;
myThread.init();
//
myThread.creatProduct();
//
myThread.creatConsumer();
myThread.destory();

3、有时我们仅使用成员函数也可以达到该回调效果,例如:

#include <boost/bind.hpp>   

#include <boost/function.hpp>   

#include <iostream>   

  

// 函数对象 接受一个参数,返回值类型为 void  

typedef boost::function<void(const std::string &)> callback;   

  

class A   

{   

public:   

    void print(const std::string &msg)   

    {   

        std::cout << msg << std::endl;   

    }   

};   

  

class B   

{   

public:   

    //设置回调函数对象  

    void set_callback(callback cb)   

    {   

        m_cb = cb;   

    }   

  

    //调用回调函数对象  

    void do_callback()   

    {   

        m_cb("message");   

    }   

  

private:   

    callback m_cb;   

};   

  

void regular_function(const std::string &msg)   

{   

    std::cout << msg << std::endl;   

}   

  

int main()   

{   

    A a;   

    B b;   

      

    //成员函数用于回调  

    b.set_callback(boost::bind(&A::print, &a, _1));   

    b.do_callback();   

  

    // 普通函数指针同样适用  

    b.set_callback(regular_function);   

    b.do_callback();   

    return 0;  

}

4、利用多态机制,主要是子类实现继承父虚基类的纯虚函数,参数传递是只需传入基类指针即可。

//虚基类

class IMessage

{

public:
//纯虚函数
virtual void OnResponse(std::string& msg) = 0;

public:
//虚析构
virtual ~IMessage() {}

};

class CMessage: public IMessage

{

public:
CMessage(void);
~CMessage(void);

public:
//实现基类纯虚函数
void OnResponse(std::string& msg);

};

//*************************************//

void CMessage::OnResponse(std::string& msg)

{
printf("response is:%s\n", msg.c_str());

}

//***********************************//

bool notify(IMessage* pMsg)

{
std::string msg = "receive success";
pMsg->OnResponse(msg);
return true;

}

int _tmain(int argc, _TCHAR* argv[])

{

CMessage pMsg;
notify(&pMsg);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: