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;
}
在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;
}
相关文章推荐
- 用C++实现简单的文件I/O操作
- 标准纯C++实现简单的词法分析器(一)
- c++ stl list 迭代器简单实现
- 单链表赋值,定位,添加,(C++ ) 简单实现 未整理
- Ping的简单实现 CODE: C /C++
- C++ : 用proxy Class实现简单的二维数组。
- C++ 简单实现委托
- C++中简单实现foreach循环
- 实例学MFC(3)--超简单C++实现网络下载器
- 大话设计模式之C++实现---简单工厂模式
- 标准纯C++实现简单的词法分析器(一)
- 标准纯C++实现简单的词法分析器(三)
- 标准纯C++实现简单的词法分析器(三)
- C++实现回调函数 funtor
- 用C++实现简单的文件I/O操作
- 用C++实现简单的文件I/O操作
- 标准纯C++实现简单的词法分析器(二)
- 用C++实现简单的文件I/O操作(ifstream,ofstream)
- 用C++实现简单的文件I/O操作(ifstream,ofstream)
- 策略模式与简单工厂的C++实现