天天看點

CallBack 回調函數

回調函數的定義:回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(位址)作為參數傳遞給另一個函數,當這個指針被用為調用它所指向的函數時,我們就說這是回調函數。

我自己的通俗了解:老鮑要蓋一棟房子(相當于一個函數方法),打地基-》壘牆-》....,要上頂了,他自己不想去上或者不知道怎麼上(方法到這暫停),但他知道我會上,因為蓋房子之前有人已經把我會上房頂這事告訴他了,要不然他不會蓋房子的,函數功能就應該達到某個功能(相當于調用的時候把回調函數的指針傳給了他),于是經理一個電話,我就把房頂上上了,然後沒我事了,經理繼續把家給裝修了一下,工作完成。

這裡“我”就是回調函數,老鮑是回調函數的調用函數

 為什麼要使用回調函數?

  因為可以把調用者與被調用者分開。調用者不關心誰是被調用者,所有它需知道的,隻是存在一個具有某種特定原型、某些限制條件(如傳回值為int)的被調用函數。

  如果想知道回調函數在實際中有什麼作用,先假設有這樣一種情況,我們要編寫一個庫,它提供了某些排序算法的實作,如冒泡排序、快速排序、shell排序、shake排序等等,但為使庫更加通用,不想在函數中嵌入排序邏輯,而讓使用者來實作相應的邏輯;或者,想讓庫可用于多種資料類型(int、float、string),此時,該怎麼辦呢?可以使用函數指針,并進行回調。

  回調可用于通知機制,例如,有時要在程式中設定一個計時器,每到一定時間,程式會得到相應的通知,但通知機制的實作者對我們的程式一無所知。而此時,就需有一個特定原型的函數指針,用這個指針來進行回調,來通知我們的程式事件已經發生。實際上,SetTimer() API使用了一個回調函數來通知計時器,而且,萬一沒有提供回調函數,它還會把一個消息發往程式的消息隊列。

  另一個使用回調機制的API函數是EnumWindow(),它枚舉螢幕上所有的頂層視窗,為每個視窗調用一個程式提供的函數,并傳遞視窗的處理程式。如果被調用者傳回一個值,就繼續進行疊代,否則,退出。EnumWindow()并不關心被調用者在何處,也不關心被調用者用它傳遞的處理程式做了什麼,它隻關心傳回值,因為基于傳回值,它将繼續執行或退出。

  不管怎麼說,回調函數是繼續自C語言的,因而,在C++中,應隻在與C代碼建立接口,或與已有的回調接口打交道時,才使用回調函數。除了上述情況,在C++中應使用虛拟方法或函數符(functor),而不是回調函數。

回調函數的應用舉例:

 1 typedef int (*callback)(int param1, char* param2);定義函數指針

 2 

 3 Syntax(句法規則)

 4     typedef return_code  (*function_virtual_name)(parameters list);

 5 

 6 Example

 7 class CCall;

 8 typedef int (*callback)(CCall* call, int i);

 9 class CCall{

10 public:

11     CCall(int i = 0)

12         : _i(i)

13     {};

14     virtual ~CCall() {}

15     

16     int becall(int i) { return call(i); }

17     virtual int call(int i) = 0;

18 private:

19     int _i;

20 };

21 

22 static int Func(CCall* call, int i)//call 為回調函數的指針

23 {

24     return call->becall(i);

25 }

26 

未完成。。。。。。

繼續閱讀