C++学习:回调函数(callback)
简介:
回调函数就是⼀个通过函数指针调⽤的函数。如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应
可能这些概念性的东西不是太好理解,通俗⼀点,回调函数就是在两个独⽴函数或者独⽴类通信的通道
举个例⼦:
财务处是负责对公司财务状况和每个⽉的开销进⾏汇总,⽼板只会去看每个⽉的报表。
那么在这个当中,⽼板不会去关⼼,财务整个汇总的过程,他只会去关⼼结果,那么,如果从⾯向对象的⽅法去理解的话,⽼板是⼀个对象.财务部是⼀个对象,当⽼板想看报表的时候,会跟财务打个招呼,等财务部汇总完了.然后将报表再去提交给⽼板,那么问题来了,⽽两个类之间实现通信的就是接⼝回调,从财务类的中,将结果回调到对象中.这种实现是通过接⼝⾃动完成的。
如果⽤C语⾔的⾯向过程去理解的话,那么⽼板想看报表可以理解为⼀个函数,⽽财务处计算过程可以
看成⼀个函数,如果⽼板想看报表的话,可以直接通过调⽤财务处函数的返回结果来查看.这中主要是依赖于函数指针的形式来实现。
基于C语⾔的回调函数来实现⼀个回调的过程
* Filename:  callback.c
*/
#include<stdio.h>
#include<stdlib.h>
/* *
*财务的统计状况函数
*/
static int finance_result(int *a,int n);
/**
*⽼板想看财务报表
*/
void boss_read_finance(int *array,int n,int (*fp)(int*,int));
int main(int argc,char* argv[]){
//定义⼀个数组数据
int array[10] = {1,2,3,4,5,6,7,8,9,10};
//因为C语⾔中函数名也是地址,因此对于形参数是函数指针的话,这个时候直接将地址传进去就可以了;  //注意:函数指针是指向函数的地址,对于fp是地址,那么调⽤的时候固然需要(*fp)
c语言如何去学//也可以这样写:
//int (*fp)(int *a,int n);
//fp = finance_result;
//boss_read_finance(array,10,finance_result);
boss_read_finance(array,10,finance_result);
return 0;
}
/**
*⽼板查看财务状况的实现,参数中有⼀个函数指针,
*/
void boss_read_finance(int* array,int n,int (*fp)(int* a,int n)){
//对于⽼板来说,他是不需要去了解财务部的具体实现的过程,只要结果就⾏了
//这就有助于我们对函数封装
int result = (*fp)(array,n);
printf("caculate result:%d\n",result);
}
/**
*财务计算报表的具体实现
*/
static int finance_result(int* a,int n){
int result = 0;
int i =  0;
for(i = 0;i < n; i++){
result += *(a+i);
}
return result;
}
基于C++⾯向对象过程的代码
#ifndef TEST1_FINANCE_H
#define TEST1_FINANCE_H
#include <iostream>
using namespace std;
class CallBack {
public:
virtual void setFinanceResult(int result) const = 0;
};
class Finance {
public:
Finance(CallBack* mCallBack2) : mCallBack(mCallBack2) {    cout << "finance constructor" << endl;
}
~Finance() {
cout << "finance destructor" << endl;
}
void caculateFinance(int *a, int n) {
int result = 0;
for (int i = 0; i < n; ++i) {
result += *(a + i);
}
if (nullptr != mCallBack) {
cout << "result: " << result << endl;
mCallBack->setFinanceResult(result);
}
}
private:
CallBack* mCallBack;
};
class Boss : public CallBack {
public:
Boss() {
mFinance = new Finance(this);
cout << "boss contructor" << endl;
}
~Boss() {
delete mFinance;
cout << "boss destructor" << endl;
}
void readFianance(int *array, int n) {
cout <<"boss readFianance" << endl;
mFinance->caculateFinance(array, n);
}
void setFinanceResult(int result) const {
cout << "caculate result: " << result << endl;
}
private:
Finance* mFinance;
};
#endif //TEST1_FINANCE_H
#include "Finance.h"
int main() {
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Boss boss;
return 0;
}
其实这个案例能够让我们对回调有更加深刻的认识:
1:⽼板想查看财务(调⽤⾃⼰函数,函数在boss内)
2:通知财务,我要查看报表(进⾏计算的过程,函数在finance内部)
3:财务算好之后,返回给⽼板(回调的函数在boss内部)
也就是回调就是把不需要⾃⼰处理的东西放到别的类去,然后等其处理完毕之后,再返回给调⽤的类.
总结:
回调四步曲:
1. 定义⼀个回调接⼝
2. 调⽤类去实现这个接⼝,重写⽅法
3. 被调⽤者将接⼝做为参数传递进去,并且在某个时刻进⾏出发
4. 调⽤者在调⽤的时候去实例化这个回调接⼝(如上述案例中因为已经实现了接⼝,所以将类本⾝对应的对象作为参数传递进去)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。