天天看點

C++的回調機制

什麼是回調

開發中經常遇到等待其他子產品事件通知的情況,例如:

  • 使用者點選UI上button的事件,通知給相關函數處理邏輯
  • Model中資料改變的事件,通知給相關View子產品重新整理界面
  • 異步IO完成的事件,通知給處理函數确認成功還是失敗
  • 用戶端向伺服器發N種不同請求,伺服器為每種請求準備好處理函數

這些等待通知的函數被執行的過程就是回調的過程,是以回調是一個很常見很簡單的事情。回調可能大家首先想到的是回調函數,回調機制包括但并不拒局限于回調函數(不過在C語言裡兩者基本相同),其核心思想就是由調用者實作部分甚至全部操作細節。這個思想的用途十分廣泛。在設計良好的C++程式中,實作回調的最主要方法應該是多态。

實作方法

(1)Callback方式。

a.Callback的本質是設定一個函數指針進去,然後在需要需要觸發某個事件時調用該方法, 比如Windows的視窗消息處理函數就是這種類型。(這就是C的回調函數而已,面向過程的,注意要使用全局函數)

C++的回調機制

b.C++裡面用類,記得定義成靜态static成員,思想與上面一樣。

C++的回調機制

為什麼不能直接使用類的非靜态函數作為回調函數呢,通俗點的解釋就是類的非靜态函數都要預設傳入一個this指針參數,這就跟我們平時的回調不同了,是以無法使用。一般的回調函數都是_stdcall或者_cdecl的調用方式,但是成員函數是__thiscall的調用方式。這種調用方式的差别導緻不能直接使用類的非靜态成員函數作為回調函數。看看差別吧:

關鍵字 堆棧清除 參數傳遞
__stdcall 被調用者 将參數倒序壓入堆棧(自右向左)
__thiscall 被調用者 壓入堆棧,this指針儲存在 ECX 寄存器中

可見兩者的不同之處就是_thiscall把this指針儲存到了ECX的寄存器中,其他都是一樣的。

(2)采用C++的非靜态成員函數實作

實作多态。(正統主流方法,大部分情況下考慮使用。太多設計模式采用這個體位了)

C++的回調機制

Sink方式。(面向對象的,在C++裡使用較多, 可以在一個Sink裡封裝一組回調接口,适用于一系列比較固定的回調事件)

Sink的本質是你按照對方要求實作一個C++接口,然後把你實作的接口設定給對方,對方需要觸發事件時調用該接口, COM中連接配接點就是居于這種方式。上面下載下傳檔案的需求,如果用Sink實作,代碼如下:

C++的回調機制
C++的回調機制
c++

繼續閱讀