在项目中看到回调函数,总结一下:
回调函数的几个条件:
- 定义一个指向函数的指针
- 声明被回调函数
- 调用回调函数的宿主函数
本例子将回调函数注册到一个map中,在消息类触发的服务器应用中常见,比如游戏服务器
话不多说:直接上代码
版本1:定义一个指向函数的指针
CallBack.h
#ifndef __CALLBACK_H__
#define __CALLBACK_H__
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef std::map<string, unsigned int> FuncMap;
typedef std::map<string, unsigned int>::iterator IterFuncMap;
typedef void (*Hook)(int, int); //函数指针
class CallBack
{
public:
CallBack();
virtual ~CallBack();
void Init();
void RegisterCallBackFunc(std::string key, Hook hookfun);//注册回调函数
void CallBackFunc(string, int, int);//调用回调函数
static void add(int a, int b); //这里必须定义为static,因为FuncMap的value为unsigned int
static void sub(int a, int b);
private:
//std::map<std::string, unsigned int> func_map;
FuncMap func_map;
};
#endif // !__CALLBACK_H__
CallBack.cpp
#include "CallBack.h"
CallBack::CallBack()
{
Init();
}
CallBack::~CallBack()
{
func_map.clear();
}
void CallBack::Init()
{
//RegisterCallBackFunc("add", add);
//这里用了两种方法将回调函数插入map
RegisterCallBackFunc("sub", sub); //法1
func_map.insert(FuncMap::value_type("add",(unsigned int)CallBack::add));//法2
cout << "initializer finish !" << endl;
}
void CallBack::add(int a, int b)
{
int res = a + b;
cout << "add res = " << res << endl;
}
void CallBack::sub(int a, int b)
{
int res = a > b ? a - b : b - a;
cout << "sub res = " << res << endl;
}
void CallBack::RegisterCallBackFunc(std::string key, Hook hookfun)
{
auto iter = func_map.find(key);
if (iter == func_map.end())
{
func_map.insert(FuncMap::value_type(key,(unsigned int)hookfun));
}
}
void CallBack::CallBackFunc(string key, int a, int b)
{
auto iter = func_map.find(key);
if (iter != func_map.end())
{
Hook func = (Hook)iter->second;
func(a, b);
}
}
版本2:用c++11 的function代替函数指针
CallBack.h
#define __CALLBACK_H__
#include <functional>
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef std::function<void(int, int)> Func;
typedef std::map<string, Func> FuncMap;
typedef std::map<string, Func>::iterator IterFuncMap;
//typedef void (*Hook)(int, int);
class CallBack
{
public:
CallBack();
virtual ~CallBack();
void Init();
void RegisterCallBackFunc(std::string key, Func func);
void CallBackFunc(string, int, int);
static void add(int a, int b);
static void sub(int a, int b);
private:
//std::map<std::string, unsigned int> func_map;
FuncMap func_map;
};
#endif // !__CALLBACK_H__
CallBack.cpp
#include "CallBack.h"
CallBack::CallBack()
{
Init();
}
CallBack::~CallBack()
{
func_map.clear();
}
void CallBack::Init()
{
RegisterCallBackFunc("add", add);
RegisterCallBackFunc("sub", sub);
//func_map.insert(FuncMap::value_type("add",(unsigned int)CallBack::add));
cout << "initializer finish !" << endl;
}
void CallBack::add(int a, int b)
{
int res = a + b;
cout << "add res = " << res << endl;
}
void CallBack::sub(int a, int b)
{
int res = a > b ? a - b : b - a;
cout << "sub res = " << res << endl;
}
void CallBack::RegisterCallBackFunc(std::string key, Func func)
{
auto iter = func_map.find(key);
if (iter == func_map.end())
{
func_map.insert(make_pair(key,func));
}
}
void CallBack::CallBackFunc(string key, int a, int b)
{
auto iter = func_map.find(key);
if (iter != func_map.end())
{
Func func = iter->second;
func(a, b);
}
}
main.cpp
#include "CallBack.h"
using namespace std;
int main()
{
CallBack call;
int a = 20, b = 10;
call.CallBackFunc("add", a, b);
call.CallBackFunc("sub", a, b);
system("pause");
return 0;
}
两种版本的最大差别就是FuncMap的value不同,一个是unsidned int ,一个是 std::function<void(int, int)>,第二种编译器必须支持c++11特性