C++:函数:回调函数:还不懂回调函数来捶我

前言

不知道你是否有这样的疑问,我们为什么需要回调函数,直接调用函数不就可以了吗?回调函数到底有什么用?程序员该如何理解回调函数了?

这篇文章就为你解答这些问题,读完这篇文章后,你的编程技术将得到质的提高。

同步调用

做一件事情,程序员传统并且最熟悉思维模式一般是这样:

  • 调用某个函数,获取结果
  • 处理获取到的结果

result = request()

handles(result)

 如果 request()函数是同步调用,只有request()函数返回拿到结果后,才能调用handle函数进行处理,request()函数返回前我们必须等待,这就是同步调用,控制流程就是这样的

 异步调用

但是如果我们想更加高效的话,那么就需要异步调用了,我们不去直接调用handle函数,而是作为参数传递给 request()

request(handle)                                                                                          

所以,我们根本不关心request什么时候真正的获取结果,这是request该关心的事情,我们只需要把获取到的结果,该怎么处理告诉request就可以了,因此 request函数可以立即返回,真正获取结果是可能在另一个线程,进程,甚至另一台机器上完成,这就是异步调用。

 

 从编程思维上看,异步调用和同步有很大的差别,如果我们把处理流程当做一个任务来的话,那么同步流程下,整个任务都是我们实现的,但是异步流程情况下:任务的处理流程被分为两部分:

  1. 第一部分,我们处理,也就是调用 request函数之前的部分。
  2. 第二部分:不是我们处理的,而是在其他线程、进程或者另一台机器完成

重点来了:

  第二部分的调用不在我们控制范围内,同时只有调用方才知道该做什么,什么时候调用,因此在这种情况下,就需要一种必要的机制-------》这个机制就是回调。

  1. 在java/Android中,我们通常定义一个接口,然后我们实现这个接口,将接口类型作为参数传给服务方,然后服务方自己决定什么时候去调用这个接口的函数(这个接口函数是我们客户端实现的).
  2. 在C++中没有Java这种类似的接口函数回调,但是C++中有函数指针这个概念,它可以做为参数传给服务端,同样也可以起到和 java类似的功能效果。

回调函数正式定义

回调函数就是一个函数和其他函数没有任何区别。

一般函数:我们自己编写函数会在自己的程序内调用,也就是说函数的编写放方式我们自己,调用方也是我们自己

回调函数:编写方是我们自己,但是函数调用方不是我们,而是我们引用的其他模块,也就是三方库,我们调用第三方库中的函数,并把回调函数传递给第三方库,第三方库中的函数调用我们编写的函数。

 回调函数实际应用:(回调函数作为事件处理函数)

  • 如上图所示:我们抽象出这样一个模型:主应用程序--------库函数--------回调函数。库函数是不知道某个节点(或者业务完成之后在去做什么)。
  • 例如接收到 网络数据、文件读取完成之后,该做什么这些只有库的使用者才知道,设计编写库的作者并不知道,也无法针对主应用程序编写具体代码,只能对外提供一个回调函数(声明一个回调函数),库的使用方来实现该函数(定义该函数),库在特定的时机,特定的节点回调该函数就可以了。
  • 我们在抽象一下:如果把接收网络数据,文件读取看做是事件也就是 event, 那么本质上我们编写的回调函数就是用来处理Event的,因此从这个角度看回调函数不过就是 event handler ,因此回调函数天然适用于 事件驱动编程 event--driven 。

同步回调

  1. 这种回到就是常说的同步回调 synchronous callbacks 、也有将其称为阻塞式回调 blocking callbacks ,或者什么修饰都没有,就是回调callback ,这是我们最熟悉 的回调方式。
  2. 当我们调用某个函数A并以参数的形式 传入回调函数后,在A返回之前 回调函数会 被执行,也就是 说我们的主程序会等待回调函数执行完成,这就是同步回调。

异步回调 

  1. 不同于同步回调,当我们调用某个函数A并以参数的形式传入回调函数后,A函数立即返回,也就是函数A并不会阻塞我们的主程序,一段时间后回调函数开始被执行,此时我们的主程序可能在忙其他任务,回调函数的执行 和我们主程序的运行同时进行。
  2. 既然我们的主程序和回调函数的执行可以同时发生 ,因此一般情况下,主程序和回调函数的执行位于不同的线程或者进程中。

 这就是所谓的异步回调,asynchronous callbacks ,也有资料称为  deferred callbacks ,名字很形象,延迟回调。

回调对应的编程思维模式

  1. 假设我们向处理某项任务,这项任务需要依赖某项服务S,我们可以将任务的处理分为两部分,调用服务S的前部分 PA ,调用服务S后面部分为 PB。
  2. 常规模式 下,PA和PB都是服务调用方执行,也就是我们自己的主程序执行  PA,等待服务S返回后再执行PB部分。
  3. 回调模式下:PA是服务调用方执行,也就是我们自己 的主程序执行PA,等待服务S返回后,服务S在去调用PB.

回调函数实作

回调函数步骤:

1、定义一个函数(普通函数即可);

2、将此函数的地址注册给调用者;

3、特定的事件或条件发生时,调用者使用函数指针调用回调函数。

// main.cpp


#include<iostream>
// 定义一个函数指针:返回值 int ,需要两个int 类型参数
typedef int (*Ptr)(int, int);

// 2:注册函数
int RegFuncation_add(Ptr pInt, int a, int b) {
	// 调用回调函数
	return pInt(a,b);
}

class OperMath
{
public:
	// 1: 回调函数
	static int add(int a, int b) {
		return a + b;
	}

	// 1: 回调函数
	static int reduce(int a, int b) {
		return a - b;
	}

	// 3: 注册函数
	void RegFuncationCallBack_add(int a, int b) {
		std::cout << RegFuncation_add(add, a, b) << std::endl;
	}

	// 3: 注册函数
	void RegFuncationCallBack_reduce(int a,int b) {
		std::cout << RegFuncation_add(reduce, a, b) << std::endl;
	}
};


int main() {
	OperMath math;
	math.RegFuncationCallBack_add(1, 2);  // 打印:3
	math.RegFuncationCallBack_reduce(2, 1); // 打印:1
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值