回調(diào)函數(shù)(Callback function)大量用于Windows的系統(tǒng)服務(wù),通過(guò)它,程序員可以安裝設(shè)備驅(qū)動(dòng)程序和消息過(guò)濾系統(tǒng),以控制Windows的有效使用。許多程序員都發(fā)現(xiàn),利用MFC或者其它的C++應(yīng)用編寫回調(diào)函數(shù)是非常麻煩的,其根本原因是回調(diào)函數(shù)是基于C編程的Windows SDK的技術(shù),不是針對(duì)C++的,程序員可以將一個(gè)C函數(shù)直接作為回調(diào)函數(shù),但是如果試圖直接使用C++的成員函數(shù)作為回調(diào)函數(shù)將發(fā)生錯(cuò)誤,甚至編譯就不能通過(guò)。通過(guò)查詢資料發(fā)現(xiàn),其錯(cuò)誤是普通的C++成員函數(shù)都隱含了一個(gè)傳遞函數(shù)作為參數(shù),亦即“this”指針,C++通過(guò)傳遞一個(gè)指向自身的指針給其成員函數(shù)從而實(shí)現(xiàn)程序函數(shù)可以訪問(wèn)C++的數(shù)據(jù)成員。這也可以理解為什么C++類的多個(gè)實(shí)例可以共享成員函數(shù)但是確有不同的數(shù)據(jù)成員。由于this指針的作用,使得將一個(gè)CALLBACK型的成員函數(shù)作為回調(diào)函數(shù)安裝時(shí)就會(huì)因?yàn)殡[含的this指針使得函數(shù)參數(shù)個(gè)數(shù)不匹配,從而導(dǎo)致回調(diào)函數(shù)安裝失敗。要解決這一問(wèn)題的關(guān)鍵就是不讓this指針起作用,通過(guò)采用以下兩種典型技術(shù)可以解決在C++中使用回調(diào)函數(shù)所遇到的問(wèn)題。這種方法具有通用性,適合于任何C++。
1). 不使用成員函數(shù),直接使用普通C函數(shù),為了實(shí)現(xiàn)在C函數(shù)中可以訪問(wèn)類的成員變量,可以使用友元操作符(friend),在C++中將該C函數(shù)說(shuō)明為類的友元即可。這種處理機(jī)制與普通的C編程中使用回調(diào)函數(shù)一樣。
2). 使用靜態(tài)成員函數(shù),靜態(tài)成員函數(shù)不使用this指針作為隱含參數(shù),這樣就可以作為回調(diào)函數(shù)了。靜態(tài)成員函數(shù)具有兩大特點(diǎn):其一,可以在沒(méi)有類實(shí)例的情況下使用;其二,只能訪問(wèn)靜態(tài)成員變量和靜態(tài)成員函數(shù),不能訪問(wèn)非靜態(tài)成員變量和非靜態(tài)成員函數(shù)。由于在C++中使用類成員函數(shù)作為回調(diào)函數(shù)的目的就是為了訪問(wèn)所有的成員變量和成員函數(shù),如果作不到這一點(diǎn)將不具有實(shí)際意義。解決的辦法也很簡(jiǎn)單,就是使用一個(gè)靜態(tài)類指針作為類成員,通過(guò)在類創(chuàng)建時(shí)初始化該靜態(tài)指針,如pThis=this,然后在回調(diào)函數(shù)中通過(guò)該靜態(tài)指針就可以訪問(wèn)所有成員變量和成員函數(shù)了。這種處理辦法適用于只有一個(gè)類實(shí)例的情況,因?yàn)槎鄠€(gè)類實(shí)例將共享靜態(tài)類成員和靜態(tài)成員函數(shù),這就導(dǎo)致靜態(tài)指針指向最后創(chuàng)建的類實(shí)例。為了避免這種情況,可以使用回調(diào)函數(shù)的一個(gè)參數(shù)來(lái)傳遞this指針,從而實(shí)現(xiàn)數(shù)據(jù)成員共享。
posted on 2009-08-29 15:45
Bluesea 閱讀(4986)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
C/C++