C++的回调机制
- 什么是回調
開發中經常遇到等待其他模塊事件通知的情況,例如:
- 用戶點擊UI上button的事件,通知給相關函數處理邏輯
- Model中數據改變的事件,通知給相關View模塊刷新界面
- 異步IO完成的事件,通知給處理函數確認成功還是失敗
- 客戶端向服務器發N種不同請求,服務器為每種請求準備好處理函數
這些等待通知的函數被執行的過程就是回調的過程,所以回調是一個很常見很簡單的事情。回調可能大家首先想到的是回調函數,回調機制包括但并不拒局限于回調函數(不過在C語言里兩者基本相同),其核心思想就是由調用者實現部分甚至全部操作細節。這個思想的用途十分廣泛。在設計良好的C++程序中,實現回調的最主要方法應該是多態。
實現方法
(1)Callback方式。
a.Callback的本質是設置一個函數指針進去,然后在需要需要觸發某個事件時調用該方法, 比如Windows的窗口消息處理函數就是這種類型。(這就是C的回調函數而已,面向過程的,注意要使用全局函數)
b.C++里面用類,記得定義成靜態static成員,思想與上面一樣。
為什么不能直接使用類的非靜態函數作為回調函數呢,通俗點的解釋就是類的非靜態函數都要默認傳入一個this指針參數,這就跟我們平時的回調不同了,所以無法使用。一般的回調函數都是_stdcall或者_cdecl的調用方式,但是成員函數是__thiscall的調用方式。這種調用方式的差別導致不能直接使用類的非靜態成員函數作為回調函數。看看區別吧:
| 關鍵字 | 堆棧清除 | 參數傳遞 |
| __stdcall | 被調用者 | 將參數倒序壓入堆棧(自右向左) |
| __thiscall | 被調用者 | 壓入堆棧,this指針保存在?ECX?寄存器中 |
可見兩者的不同之處就是_thiscall把this指針保存到了ECX的寄存器中,其他都是一樣的。
(2)采用C++的非靜態成員函數實現
實現多態。(正統主流方法,大部分情況下考慮使用。太多設計模式采用這個體位了)
Sink方式。(面向對象的,在C++里使用較多, 可以在一個Sink里封裝一組回調接口,適用于一系列比較固定的回調事件)
Sink的本質是你按照對方要求實現一個C++接口,然后把你實現的接口設置給對方,對方需要觸發事件時調用該接口, COM中連接點就是居于這種方式。上面下載文件的需求,如果用Sink實現,代碼如下:
總結
- 上一篇: 为什么设计师应该学习编写代码
- 下一篇: 图像、帧、片、NALU(firstime