回调函数概念与巧妙的实例

1.什么是回调函数?

照顾到部分同学可能跟我之前一样,对回调函数概念还不是很明确,还请容许我在这解释一遍。熟练的可以直接跳到进阶实例
先来个简单的解释:回调函数就是一个通过函数指针调用的函数。如果你把一个函数的地址作为参数赋值给一个函数指针,当这个指针被用来调用其所指向的函数时,称之为回调函数。

//简单的代码说明
/*
假设存在需求:A进程中需要B进程通过A的方法通知其某一件事是否完成!!
*/
// 类型重定义方便后面书写
typedef void (*cb)(int i);
//B进程负责通知,则B进程定义“函数指针”
class B{
	public:
		//设置回调函数的方法
		void setcallback(cb p)
		{
			//回调函数的精髓:将实际需要调用方法设置到函数指针中
			//务必理解:这个赋值语句执行后,pCb指向传值进来的函数
			this->pCb = p;
		}
	public:
		cb pCb;//这只是个指针,是个“壳”
};

//A进程提供通知方法/函数(B进程通过此方法通知A进程)
class A{
	public:
		//真正执行的函数,B用此方法通知A。
		void func(int i)
		{
			cout<<"我完成了事件:"<<i<<endl;
		}
};
//使用:在A的进程/线程中:
A pA = new A;
B pB = new B;
pB->setcallback(pA->func);//约等于A告诉B:你做好了就通过这个方法告诉我
//使用:在B进程中,B完成某事之后
pB->pCb(5)//相当于===>>>pA->func(5);

至此,相信大家对回调函数应该有个小小的认识了。回调最根本的思想无非就是:其他进程(或模块)通过本进程(或模块)实现的(回调)函数,来通知本进程(模块)某些消息。不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。其中,设置回调函数(setcallback)这个动作一般称之为注册

2.巧妙实例(本文主讲)

话不多说直接上代码

class B{
	public:
	//声明回调函数类
	//专门用于被派生类重载的纯虚函数,嵌套类纯虚函数不会影响实例化
	class CallBack{
		public: 
			virtual void onCallBackB(int i) = 0;
	}
	void setCallBack(CallBack *p){
		this->pCb = p;
	}
	public:
		CallBack  pCb;
};
class A: public B::CallBack{
	public:
	//重载B::onCallBackB方法
	void onCallBackB(int i){
		cout<<"方法是A实现的,事件是:"<<i<<endl;
	}
	A(){
		oB = new B;
		//注册回调
		//形参是CallBack类,实参是A类,你品,你细品!
		oB->setCallBack(this);
	}
	B *oB;
	//析构我就不啰嗦了......
};
int main()
{
	A* oA = new A;
	//模拟B中其他事件发生需要通知到A外部调用
	//想象是直接调用oB->pCb(5);
	oA ->oB->pCb(5);
	return 0;
}

3.小小总结一下

将可能需要通知到其他进程(模块)写进Callback嵌套类中,并修饰为纯虚函数,添加CallBack类函数指针。派生类通过继承父类中的Callback(注意这里不是直接继承B类),对父类CallBack进行重载,在调用父类的注册接口将this指针注册进父类(观察该接口的形参与实参形式,不难发现这里体现了多态,就是CallBack中声明为纯虚函数的原因)。而且当派生类需要多个模块的回调通知时,同时继承多个嵌套类的callback并不会互相冲突!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值