作业(二)——学习callback回调函数
简介:
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应
可能这些概念性的东西不是太好理解,通俗一点,回调函数就是在两个独立函数或者独立类通信的通道
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应
可能这些概念性的东西不是太好理解,通俗一点,回调函数就是在两个独立函数或者独立类通信的通道
举个例子:
财务处是负责对公司财务状况和每个月的开销进行汇总
老板只会去看每个月的报表
老板只会去看每个月的报表
那么在这个当中,老板不会去关心,财务整个汇总的过程,他只会去关心结果,那么,如果从面向对象的方法去理解的话,老板是一个对象.财务部是一个对象,当老板想看报表的时候,会跟财务打个招呼,等财务部汇总完了.然后将报表再去提交给老板,那么问题来了,而两个类之间实现通信的就是接口回调,从财务类的中,将结果回调到对象中.这种实现是通过接口自动完成的
如果用C语言的面向过程去理解的话,那么老板想看报表可以理解为一个函数,而财务处计算过程可以看成一个函数,如果老板想看报表的话,可以直接通过调用财务处函数的返回结果来查看.这中主要是依赖于函数指针的形式来实现。
如果用C语言的面向过程去理解的话,那么老板想看报表可以理解为一个函数,而财务处计算过程可以看成一个函数,如果老板想看报表的话,可以直接通过调用财务处函数的返回结果来查看.这中主要是依赖于函数指针的形式来实现。
/* * =========================================================================== * * Filename: callback.c * Description: * Version: 1.0 * Created: 2017年07月09日 10时27分28秒 * Revision: none * Compiler: gcc * Author: (), * Company: * * =========================================================================== */ #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) //也可以这样写: //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; }
/* * =========================================================================== * * Filename: callback.c * Description: * Version: 1.0 * Created: 2017年07月09日 10时27分28秒 * Revision: none * Compiler: gcc * Author: (), * Company: * * =========================================================================== */ #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) //也可以这样写: //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; }
/* * =========================================================================== * * Filename: finance.h * Description: * Version: 1.0 * Created: 2017年07月09日 10时52分53秒 * Revision: none * Compiler: gcc * Author: (), * Company: * * =========================================================================== */ #ifndef __FINANCE_H__ #define __FINANCE_H__ namespace zzf{ #include<iostream> using namespace::std; /* * *定义一个callback的接口 * */ 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(mCallBack != NULL){ cout <<"result:"<<result<<endl; mCallBack->setFinanceResult(result); } } private: CallBack* mCallBack; }; /* * *老板,实现接口callback * */ class Boss:public CallBack{ public: Boss(){ //将接口实例化后,传递给Finance mFinace = new Finance(this); cout << "boss constructor" << endl; } ~Boss(){ delete mFinace; cout << "boss destructor" << endl; } //查看财务的函数 void readFianace(int *array ,int n){ cout << "boss readFianace"<< endl; mFinace -> caculateFinance(array,n); } //实现后的回调函数,这个函数就是用来接收回调的值的 void setFinanceResult(int result) const{ cout << "caculate result:" << result << endl; } private: Finance *mFinace; }; } #endif
其实这个案例能够让我们对回调有更加深刻的认识:
1:老板想查看财务(调用自己函数,函数在boss内)
2:通知财务,我要查看报表(进行计算的过程,函数在finance内部)
3:财务算好之后,返回给老板(回调的函数在boss内部)
也就是回调就是把不需要自己处理的东西放到别的类去,然后等其处理完毕之后,再返回给调用的类.
1:老板想查看财务(调用自己函数,函数在boss内)
2:通知财务,我要查看报表(进行计算的过程,函数在finance内部)
3:财务算好之后,返回给老板(回调的函数在boss内部)
也就是回调就是把不需要自己处理的东西放到别的类去,然后等其处理完毕之后,再返回给调用的类.
总结:
回调四步曲:
回调四步曲:
定义一个回调接口
调用类去实现这个接口,重写方法
被调用者将接口做为参数传递进去,并且在某个时刻进行出发
调用者在调用的时候去实例化这个回调接口(如上述案例中因为已经实现了接口,所以将类本身对应的对象作为参数传递进去)

浙公网安备 33010602011771号