怎么實(shí)現(xiàn)類的成員函數(shù)作為回調(diào)函數(shù)
如果試圖直接使用C++的成員函數(shù)作為回調(diào)函數(shù)將發(fā)生錯(cuò)誤,甚至編譯就不能通過(guò)。其錯(cuò)誤是普通的C++成員函數(shù)都隱含了一個(gè)傳遞函數(shù)作為參數(shù),亦即“this”指針,C++通過(guò)傳遞this指針給其成員函數(shù)從而實(shí)現(xiàn)程序函數(shù)可以訪問(wèn)C++的數(shù)據(jù)成員。這也可以理解為什么C++類的多個(gè)實(shí)例可以共享成員函數(shù)卻-有不同的數(shù)據(jù)成員。由于this指針的作用,使得將一個(gè)CALL-BACK型的成員函數(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ù),為了訪問(wèn)類的成員變量,可以使用友元操作符(friend),在C++中將該函數(shù)說(shuō)明為類的友元即可。
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ù)成員共享。這種方法稍稍麻煩,這里就不再贅述。
首先明白什么是回調(diào)函數(shù):比如說(shuō)被調(diào)函數(shù)void callbackf(int n){}要想作為回調(diào)函數(shù)的話,callbackf必須作為主調(diào)函數(shù)的形參出現(xiàn),如void f(void (*p(int)),int n)形式才行!
例子:
例1:
#include<iostream>
using namespace std;
class A
{
public:
friend void callback() //友元函數(shù)作為回調(diào)函數(shù) friend方式實(shí)現(xiàn)
{
cout<<"回調(diào)函數(shù)開(kāi)始執(zhí)行了!"<<endl;
}
};
void f(void (*p)())
{
p();
}
int main()
{
void (*p)();
p=callback;
f(p);
return 0;
}
例2:
#include<iostream>
using namespace std;
class A
{
public:
static void callback() //類的成員函數(shù)作為回調(diào)函數(shù) static方式實(shí)現(xiàn)
{
cout<<"回調(diào)函數(shù)開(kāi)始執(zhí)行了!"<<endl;
}
};
void f(void (*p)())
{
p();
}
int main()
{
void (*p)();
p=A::callback;
f(p);
return 0;
}
還可以把f()函數(shù)設(shè)為類的成員函數(shù):
#include<iostream>
using namespace std;
class A
{
public:
static void callback() //類的成員函數(shù)作為回調(diào)函數(shù) static方式實(shí)現(xiàn)
{
cout<<"回調(diào)函數(shù)開(kāi)始執(zhí)行了!"<<endl;
}
void f(void (*p)())
{
p();
}
};
int main()
{
A a;
void (*p)();
p=A::callback;
a.f(p);
return 0;
}
- 實(shí)例解析C++中類的成員函數(shù)指針
- 詳解C++成員函數(shù)的override和final說(shuō)明符的用法
- C++中與輸入相關(guān)的istream類成員函數(shù)簡(jiǎn)介
- 深入解析C++編程中的靜態(tài)成員函數(shù)
- 詳解C++編程中類的成員變量和成員函數(shù)的相關(guān)知識(shí)
- C++之普通成員函數(shù)、虛函數(shù)以及純虛函數(shù)的區(qū)別與用法要點(diǎn)
- C++在成員函數(shù)中使用STL的find_if函數(shù)實(shí)例
- C++普通函數(shù)指針與成員函數(shù)指針實(shí)例解析
- 類成員函數(shù)的重載、覆蓋與隱藏之間的區(qū)別總結(jié)
- 淺析成員函數(shù)和常成員函數(shù)的調(diào)用
相關(guān)文章
C++ CryptoPP使用AES實(shí)現(xiàn)加解密詳解
Crypto++ (CryptoPP) 是一個(gè)用于密碼學(xué)和加密的 C++ 庫(kù),提供了大量的密碼學(xué)算法和功能,這篇文章主要為大家介紹了C++ CryptoPP如何使用AES實(shí)現(xiàn)加解密,需要的可以參考下2023-11-11
C++實(shí)現(xiàn)接兩個(gè)鏈表實(shí)例代碼
這篇文章主要介紹了C++實(shí)現(xiàn)接兩個(gè)鏈表實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-03-03
C語(yǔ)言 動(dòng)態(tài)內(nèi)存分配詳解
這篇文章主要介紹了C語(yǔ)言 動(dòng)態(tài)內(nèi)存分配詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06
c++結(jié)合opencv如何實(shí)現(xiàn)讀取多張圖片并顯示
這篇文章主要介紹了c++結(jié)合opencv如何實(shí)現(xiàn)讀取多張圖片并顯示問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
CLion搭建配置C++開(kāi)發(fā)環(huán)境的圖文教程 (MinGW-W64 GCC-8.1.0)
這篇文章主要介紹了CLion搭建配置C++開(kāi)發(fā)環(huán)境的教程 (MinGW-W64 GCC-8.1.0),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02

