1. 程式人生 > >C++成員函式作為回撥函式的問題

C++成員函式作為回撥函式的問題

1. 程式設計分兩類 一,應用程式設計和系統程式設計 系統程式設計就是編寫底層的庫, 應用程式設計就是利用已經編寫好的庫的介面來編寫某種具有某些功能的程式,即應用 所謂的庫,就是為了給應用提供介面,以方便程式設計師使用 2. 回撥函式 當程式跑起來的時候,一般情況,應用程式會通過直接呼叫庫裡準備好的介面 但是: 有些庫函式卻需要應用先傳遞一個函式,好在合適的時候被呼叫,而這個傳入的函式就是回撥函式 3. 舉例 打個比方,有一家旅館提供叫醒服務,但是要求旅客自己決定叫醒的方法。可以是打客房電話,也可以是派服務員去敲門,睡得死怕耽誤事的,還可以要求往自己頭上澆盆水。這裡,“叫醒”這個行為是旅館提供的,相當於庫函式,但是叫醒的方式是由旅客決定並告訴旅館的,也就是回撥函式。而旅客告訴旅館怎麼叫醒自己的動作,也就是把回撥函式傳入庫函式的動作,
稱為登記回撥函式to register a callback function)。如下圖所示(圖片來源:維基百科):
4. C++中類成員函式作為回撥函式的問題 回撥函式是基於C程式設計的Windows SDK的技術,不是針對C++的,程式設計師可以將一個C函式直接作為回撥函式,但是如果試圖直接使用C++的成員函式作為回撥函式將發生錯誤,甚至編譯就不能通過。 普通的C++成員函式都隱含了一個傳遞函式作為引數,亦即“this”指標,C++通過傳遞一個指向自身的指標給其成員函式從而實現程式函式可以訪問C++的資料成員。這也可以理解為什麼C++類的多個例項可以共享成員函式但是確有不同的資料成員。
由於this指標的作用,使得將一個CALLBACK型的成員函式作為回撥函式安裝時就會因為隱含的this指標使得函式引數個數不匹配,從而導致回撥函式安裝失敗。 這樣從理論上講,C++類的成員函式是不能當作回撥函式的。但我們在用C++程式設計時總希望在類內實現其功能,即要保持封裝性,如果把回撥函式寫作普通函式有諸多不便。經過網上搜索和自己研究,發現了幾種巧妙的方法,可以使得類成員函式當作回撥函式使用。 方法一:回撥函式為普通函式,但在函式體內執行成員函式 : 即在成員函式內部,登記回撥函式; 方法二:設定回撥函式為static,然後以 類名::函式 的方式呼叫 方法三:回撥函式宣告在類外,全域性的傳類物件指標給回撥函式即可使用類內成員,因為回撥函式是全域性的所以影響了類的封裝性