一、簡介
本文主要介紹C++中如何使用回呼函式,
二、回呼函式介紹
回呼函式主要在“回”字,和正常的函式呼叫方式不太一樣,正常的函式由開發者自己定義回傳型別以及傳入的引數,并且也是由開發者自己呼叫,而回呼函式功能其實也是由開發者自己實作,但是回傳型別以及入參則由注冊回呼的函式來決定(若是自己撰寫則可以自定義注冊函式,由他人提供則只能根據介面實作),而且呼叫方也不是開發者,而是注冊方決定,
整個程序也就是一個“回”字,開發者將自己的函式指標交給對方,這是“去”,而對方則在適當的時候呼叫這個函式,也可以將一些開發者需要的資料傳回來,這便是來回了,
總而言之,正常情況是開發者呼叫API,呼叫權在開發者手中,而回呼函式則相當于API呼叫開發者提供的函式,主被動轉換了,
三、回呼函式用處
那么,回呼函式的用處是什么呢?既然發明了回呼函式,自然是有其用武之地了,
如果你對上面的解釋比較理解的話,你就會發現回呼函式真的用的很多,比如事件,其底層就是回呼函式,比如最簡單的UI視窗滑鼠點擊事件,是否是由開發者撰寫函式具體實作,而呼叫的時機是由UI框架決定呢?不過很多開發者可能由于框架封裝的十分簡單易用,所以沒有察覺到,
四、回呼函式示例
了解了概念后,我們自然是要學習如何自己實作回呼函式的注冊了,本文以C++為例,
void sample(void (*callback)()) { callback(); }void callbackFun1() { std::cout << "call the function1" << std::endl; }
void callbackFun2() { std::cout << "call the function2" << std::endl; }
int main() { sample(callbackFun1); sample(callbackFun2); std::system("pause");
return 0; }

如上所示,這便是最簡單的回呼函式了,
sample函式的入參為void (*callback) (),共有三部分,void 表示回傳型別,(*callback)為函式指標,() 則代表回呼函式的入參,此處無入參,
因此只要是回傳型別為void,引數為空的函式,sample都能夠呼叫,
一般為了方便呼叫,都會使用typedef,如下,
typedef int (*myFun) (int&, int); int sample(myFun mF, int& a, int b) { b = 2; return mF(a, b); } int callbackFun1(int& a, int b) { a++; return a+b; } int main() { int a = 0; int b = 1; int c = sample(callbackFun1, a, b); std::cout << "a = " << a << " b = " << b << " c = " << c << std::endl; std::system("pause"); return 0; }

結果是否和你計算的一樣呢?
以上都是直接觸發,但是大部分框架可就復雜多了,可不是這么簡單的呼叫,只會在需要的時候才會觸發!
typedef int (*myFun) (int&, int); struct fun { myFun mF; int a; int b; fun(myFun _mF, int _a, int _b) { mF = _mF; a = _a; b = _b; } }; std::vector<fun> funs; void regisiterCallback(myFun mF, int& a, int b) { funs.emplace_back(fun(mF, a, b)); } int callbackFun1(int& a, int b) { return a+b; } int main() { int a = 0; int b = 0; regisiterCallback(callbackFun1, a, b); a++; b++; regisiterCallback(callbackFun1, a, b); std::cout << funs[1].mF(funs[1].a, funs[1].b) << std::endl; std::cout << funs[0].mF(funs[0].a, funs[0].b) << std::endl; std::system("pause"); return 0; }

如上regisiter函式只是負責注冊回呼,并沒有觸發回呼函式,在main中才真正呼叫,并且我特意先呼叫了第二個注冊的回呼,結果也是先輸出了第二個注冊的回呼,因此回呼函式的呼叫先后順序與注冊順序沒有關系,只跟注冊方實際呼叫順序有關,
五、總結
本文內容為我個人之談,如有錯誤,歡迎指正!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/506542.html
標籤:其他
上一篇:python學習:三目運算子
下一篇:01-MyBatisPlus簡介
