在项目中看到回调函数,总结一下:
回调函数的几个条件:

  1. 定义一个指向函数的指针
  2. 声明被回调函数
  3. 调用回调函数的宿主函数

本例子将回调函数注册到一个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特性

在项目中看到回调函数,总结一下:回调函数的几个条件:定义一个指向函数的指针声明被回调函数调用回调函数的宿主函数本例子将回调函数注册到一个map中,在消息类触发的服务器应用中常见,比如游戏服务器话不多说:直接上代码版本1:定义一个指向函数的指针CallBack.h#ifndef __CALLBACK_H__#define __CALLBACK_H__#include &lt;iostream&gt;#include &lt;map&gt;#include &lt;string& 在module对象的enable方法中的on函数(该on函数是context中的那个,是Module的on函数的封装)调用实现了当前module对依赖模块的defined事件的订阅。 箭头处则是事件发生的时候所执行的回调函数,但是需要注意的是,这里的回调函数并不 typedef void(*fun)(QString id, QString str); //存放调用函数类型和函数指针的map static std::map<QString, fun> callbackfun_map; // 要被回调函数 void test(QString id,QString str) cout << id << ":" <... CSDN-Ada助手: 非常感谢您分享 qemu-6.1 版本编译的文章!您的经验与技巧对其他开发者来说一定非常有用。我们期待更多您分享技术方面的知识。如果您感兴趣,我们建议您可以分享一篇有关虚拟化技术的博文,比如如何使用 QEMU 进行系统虚拟化或 Docker 容器化的实践经验。谢谢您的支持与分享! 为了方便博主创作,提高生产力,CSDN上线了AI写作助手功能,就在创作编辑器右侧哦~(https://mp.csdn.net/edit?utm_source=blog_comment_recall )诚邀您来加入测评,到此(https://activity.csdn.net/creatActivity?id=10450&utm_source=blog_comment_recall)发布测评文章即可获得「话题勋章」,同时还有机会拿定制奖牌。 define中的特殊符号\,#,##的作用 qq_42971937: define多行宏定义不能这样使用if,会报错! C++11 function类模板 Bug.Remove(): 建议大哥代码好歹执行一遍再贴上去,这代码挺多错误,虽然都是小错误 C++中一个类成员函数调用另一个类成员的方法 konosubameguminn: 很有帮助,感谢 C++11 bind函数 干锅土鸡: func2的注释写错了,他的类型是:function<int()>