1. 程式人生 > >關於回撥函式的本質及比喻和例項分析

關於回撥函式的本質及比喻和例項分析

#include <iostream>
using namespace std;

typedef void (*PF)();
void func()
{
  cout << "func" << endl;
}

void caller( PF pf)
{
  pf();
}

int main()
{
  PF p = func;
  caller(p);

  system("pause");

  return 0;
}
回撥函式。高層呼叫了底層,底層反過來回調了頂層。lib用的是指標。回撥函式是最終被呼叫的那個。
https://www.zhihu.com/question/19801131

來源2

連結:http://www.zhihu.com/question/19801131/answer/13005983
來源:知乎

你到一個商店買東西,剛好你要的東西沒有貨,於是你在店員那裡留下了你的電話,過了幾天店裡有貨了,店員就打了你的電話,然後你接到電話後就到店裡去取了貨。在這個例子裡,你的電話號碼就叫回調函式,你把電話留給店員就叫登記回撥函式,店裡後來有貨了叫做觸發了回撥關聯的事件,店員給你打電話叫做呼叫回撥函式,你到店裡去取貨叫做響應回撥事件。回答完畢。
code和data本質是一樣的東西。呼叫指標和呼叫資料一樣的 來源1
連結:http://www.zhihu.com/question/19801131/answer/17156023
來源:知乎

來到這裡,其實已經沒有什麼好說的了。回撥函式也就是是A讓B做事,B做著做著,資訊不夠,不知道怎麼做了,就再讓外面處理。

比如排序,A讓B排序,B會做排序,但排序需要知道哪個比哪個大,這點B自己不知道,就需要A告訴它。而這種判斷那個大,本身是一種動作,既然C語言中不可以傳進第一值的函式,就設計成傳遞第二值的函式指標,這個函式指標就是A傳向B的資訊,用來表示一個行為。這裡本來A呼叫B的,結果B又呼叫了A告訴它的資訊,也就叫callback。 自己總結
main呼叫了caller這個函式。但是caller用了main的p指標。p為回撥函式。main呼叫了caller,但是caller執行中發現東西不夠,又回訪main中的func。這就叫回調。你去店裡買東西。電話為回撥函式。你呼叫了店員,店員後來發現有貨了但是資訊不夠,就用回撥函式電話號碼響應了你原來的東西。 回撥函式可以把呼叫者和被呼叫者分開,呼叫者不關心誰是被呼叫者,所有它需知道的,只是存在一個具有某種特定原型、某些限制條件(如返回值為int)的被呼叫函式。回撥函式就好像是一箇中斷處理函式,系統在符合你設定的條件時自動呼叫。 main不用知道caller呼叫了誰,main不知道func,他只是知道形式就好。
dll也是一種回撥機制。
CALLBACK VOID callback_fun(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
	TRACE("CallBack\n");//debug下執行控制檯輸出CallBack
}

void CTestCallBackDlg::OnBnClickedButton1()
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	SetTimer(1,1000,(TIMERPROC)callback_fun);//每一秒回撥一次
}

這個程式碼段裡首先定義回撥函式,然後定義一個被呼叫函式。主調函式是系統,也就是滑鼠點選的時候。這樣本質還是系統呼叫了回撥函式。 如何呼叫

 使用回撥函式,我們需要做三件事:

  • 宣告
  • 定義
  • 設定觸發條件:在你的函式種把你的回撥函式名稱轉化為地址作為一個引數,以便於系統呼叫。

    宣告和定義時應注意,回撥函式由系統呼叫,所以可以認為它屬於windows系統,不要把它當作你的某個類的成員函式。

    回撥函式是一個程式設計師不能顯示呼叫的函式,通過將回調函式的地址傳給呼叫者從而實現呼叫。回撥函式是十分必要的,在我們想通過一個統一介面實現不同的內容,這時回撥函式非常合適。