C++ 回调函数的实现

回调函数介绍

什么是回调函数?官方解释是回调函数就是一个被作为参数传递的函数。一句话解释言简意赅,但也有点晦涩难懂,听完后依旧不知道如何使用回调函数,以及应该在什么业务场景下使用回调函数。

所谓回调,就是模块A要通过模块B的某个函数b()完成一定的功能,但是函数b()自己无法实现全部功能,需要反过头来调用模块A中的某个函数a()来完成,这个a()就是回调函数。

举个业务逻辑的例子:某个业务需求实现方式是:对象A和对象B都调用对象C的fun()方法来完成某个计算,并且fun()会将计算结果保存为txt格式;突然某天需求变更了,A需要将结果保存为Raw格式,B需要将结果保存为bmp格式。现在C的fun()函数实现无法满足业务需求,因此 A, B,C商议 这个保存结果的功能由A,B 自己实现,因为不确定以后还会有什么需求变更。

//这里假设C的fun函数实现如下功能
void C::fun()
{
	calculate1();
	save();//save已经不满足要求,需要根据A和B不同的需求实现不同的save()
	calculate2();
}

怎么实现这个功能呢,这时候就需要回调机制了。

回调函数实现

先了解下回调函数机制:
1、定义一个函数(普通函数即可);
2、将此函数的地址注册给调用者;
3、特定的事件或条件发生时,调用者使用函数指针调用回调函数

函数指针实现回调函数

函数指针实现方式就是上述所说的将函数指针当作参数传递。

typedef int(*callbackFun)(std::string, int);
int DefaultSave(std::string s, int num)
{
	printf("DefaultSave() 函数执行\n");
	printf("默认保存为Txt格式。\n");
	return 0;
}
class SaveObj
{
public:
	SaveObj()
	{
		callback = DefaultSave;
	}
	void SetCallBack(callbackFun pFun) { callback = pFun; }
	int Save()
	{
		callback(std::string("函数指针callback"), 0);
		return 0;
	}

private:
	callbackFun callback;
};

class TestObj1
{
public:
	void CalAlgo1() { m_SaveObj.Save(); }
	void CalAlgo2()
	{
		m_SaveObj.SetCallBack(SaveRaw);
		m_SaveObj.Save();
	}
private:
	static int SaveRaw(std::string, int)
	{
		printf("TestObj1::SaveRaw()函数执行。\n");
		printf("保存为Raw格式。\n");
		return 0;
	}
private:
	SaveObj m_SaveObj;
};

namespace test
{
	int SaveRaw(std::string, int)
	{
		printf("TestObj2::SaveRaw()函数执行。\n");
		printf("保存为bmp格式。\n");
		return 0;
	}
}
class TestObj2
{
public:
	void CalAlgo()
	{
		m_SaveObj.SetCallBack(test::SaveRaw);
		m_SaveObj.Save();
	}
private:
	SaveObj m_SaveObj;
};
int main()
{
	//1. 函数指针实现回调函数
	TestObj1 obj1;
	obj1.CalAlgo1();
	obj1.CalAlgo2();
	TestObj2 obj2;
	obj2.CalAlgo();
	return 0;
}

bind实现回调函数

借助std::bind实现回调机制,下面只介绍类的静态成员函数和全局函数的实现机制。

typedef std::function <int(std::string, int)> funObj;
int DefaultSave(std::string s, int num)
{
	printf("DefaultSave() 函数执行\n");
	printf("默认保存为Txt格式。\n");
	return 0;
}
class SaveObj
{
public:
	SaveObj()
	{
		m_funObj = DefaultSave;
	}
	void SetCallBack(funObj pFun) { m_funObj = pFun; }

	int Save()
	{
		m_funObj(std::string("function 对象"), 0);
		return 0;
	}

private:
	funObj m_funObj;
};

class TestObj1
{
public:
	void CalAlgo1() { m_SaveObj.Save(); }
	void CalAlgo2()
	{
		funObj fun1 = &SaveRaw;
		m_SaveObj.SetCallBack(fun1);
		m_SaveObj.Save();
	}
private:
	static int SaveRaw(std::string, int)
	{
		printf("TestObj1::SaveRaw()函数执行。\n");
		printf("保存为Raw格式。\n");
		return 0;
	}

private:
	SaveObj m_SaveObj;
};

namespace test
{
	int SaveRaw(std::string, int)
	{
		printf("TestObj2::SaveRaw()函数执行。\n");
		printf("保存为bmp格式。\n");
		return 0;
	}
}
class TestObj2
{
public:
	void CalAlgo()
	{

		funObj fun1 = &test::SaveRaw;
		m_SaveObj.SetCallBack(fun1);
		m_SaveObj.Save();
	}

private:
	SaveObj m_SaveObj;
};
int main()
{
	//std::bind实现回调函数
	//bind绑定普通函数,类成员函数,类静态成员函数	
	TestObj1 obj1;
	obj1.CalAlgo1();
	obj1.CalAlgo2();
	TestObj2 obj2;
	obj2.CalAlgo();
	return 0;
}

目前已经实现函数指针和bind实现函数机制的方式。根据不同的业务逻辑需求选择是否使用回调函数。关于函数指针和bind的具体用法,可以参考相关博客。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值