假设有AB两个类,B类是我们自己写的应用类,A类为第三方类相机类,如下!
在设计A类的时候,该类的设计者肯定想把相机采集到的图片实时传递给应用者(此时是我们B类),而我们B类在设计应用程序的时候也想实时获取到相机采集到的图片,那B类中该怎么做呢?第一想到的方法就
是一直死循环轮询A类对象调用相关成员函数获取到实时图像。这种方式无疑不造成一种资源的浪费,而且占用很大的CPU资源。
那么有没有一种方式,当只有A类采集到图像的时候才去通知B类去获取图像这样的方式呢?答案是有的,这就引出我们今天讨论的主题:回调函数!
回调函数主要过程就是:把B类的函数注册(传递函数指针)给 A类,当A类采集到图像,就调用刚注册进来的B类函数,这样就间接完成了,由A类去通知B类去做某事
由以上图可知,把B类的函数注册给了A类。
知道了回调函数的用意,接下来就是编写代码演示过程
此次演示,我们使用c++11标准来编写代码
#include <iostream> #include <functional> using namespace std; /*回调函数原型声明*/ typedef function<void(int)> CALLBACK; /*相机SDK底层A类*/ class A_Camera { public: void regeditCallBack(CALLBACK fun)/*注册回调函数*/ { _fun = fun; } void getFrame()/*内部获取图像函数(B类调用者不需要关心它什么时候会执行)*/ { /*采集到一帧数据_frame*/ /****内部操作***/ /***内部操作***/ _frame = rand() % 10; _fun(_frame);/*回传给B_My类*/ } private: int _frame; CALLBACK _fun; }; /*应用层B类*/ class B_My { public: void callBackFun(int frame)/*获取到A类的图像,此时frame就是一帧数据*/ { cout << "B类获取到一帧数据:" << frame << endl; } }; int main(int argc, char **argv) { /*声明应用层B类对象*/ B_My B; auto Fun = bind(&B_My::callBackFun, B, placeholders::_1);/*中转一下,利用C++11特性*/ /*声明底层相机A类*/ A_Camera camera; camera.regeditCallBack(Fun);/*把B类的方法注册给A类*/ /*以下只是模拟A类内部触发获取到图片,一共模拟触发10次*/ for (int i = 0; i < 10; ++i) { camera.getFrame(); } return 0; }
运行结果
通过相机回调的方式,简单的对回调函数进行一次分析,第一次接触时回调函数机制会有点困难,但多看几遍心里就会有点感觉。例子涉及到c++11方面的知识,可以暂时忽略,不影响对回调函数的理解