怎么實(shí)現(xiàn)類的成員函數(shù)作為回調(diào)函數(shù)
如果試圖直接使用C++的成員函數(shù)作為回調(diào)函數(shù)將發(fā)生錯(cuò)誤,甚至編譯就不能通過。其錯(cuò)誤是普通的C++成員函數(shù)都隱含了一個(gè)傳遞函數(shù)作為參數(shù),亦即“this”指針,C++通過傳遞this指針給其成員函數(shù)從而實(shí)現(xiàn)程序函數(shù)可以訪問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ù)安裝失敗。要解決這一問題的關(guān)鍵就是不讓this指針起作用,通過采用以下兩種典型技術(shù)可以解決在C++中使用回調(diào)函數(shù)所遇到的問題。這種方法具有通用性,適合于任何C++。
1). 不使用成員函數(shù),為了訪問類的成員變量,可以使用友元操作符(friend),在C++中將該函數(shù)說明為類的友元即可。
2). 使用靜態(tài)成員函數(shù),靜態(tài)成員函數(shù)不使用this指針作為隱含參數(shù),這樣就可以作為回調(diào)函數(shù)了。靜態(tài)成員函數(shù)具有兩大特點(diǎn):其一,可以在沒有類實(shí)例的情況下使用;其二,只能訪問靜態(tài)成員變量和靜態(tài)成員函數(shù),不能訪問非靜態(tài)成員變量和非靜態(tài)成員函數(shù)。由于在C++中使用類成員函數(shù)作為回調(diào)函數(shù)的目的就是為了訪問所有的成員變量和成員函數(shù),如果做不到這一點(diǎn)將不具有實(shí)際意義。解決的辦法也很簡(jiǎn)單,就是使用一個(gè)靜態(tài)類指針作為類成員,通過在類創(chuàng)建時(shí)初始化該靜態(tài)指針,如pThis=this,然后在回調(diào)函數(shù)中通過該靜態(tài)指針就可以訪問所有成員變量和成員函數(shù)了。 這種處理辦法適用于只有一個(gè)類實(shí)例的情況,因?yàn)槎鄠€(gè)類實(shí)例將共享靜態(tài)類成員和靜態(tài)成員函數(shù),這就導(dǎo)致靜態(tài)指針指向最后創(chuàng)建的類實(shí)例。為了避免這種情況,可以使用回調(diào)函數(shù)的一個(gè)參數(shù)來傳遞this指針,從而實(shí)現(xiàn)數(shù)據(jù)成員共享。這種方法稍稍麻煩,這里就不再贅述。
首先明白什么是回調(diào)函數(shù):比如說被調(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ù)開始執(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ù)開始執(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ù)開始執(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說明符的用法
- 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)文章
Qt實(shí)現(xiàn)實(shí)時(shí)鼠標(biāo)繪制圖形
這篇文章主要介紹了Qt中QGraphicsView架構(gòu)下如何實(shí)現(xiàn)實(shí)時(shí)鼠標(biāo)繪制圖形,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起動(dòng)手試一試2022-02-02C語言的abs()函數(shù)和div()函數(shù)你了解嗎
這篇文章主要為大家詳細(xì)介紹了C語言的abs()函數(shù)和div()函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02C語言結(jié)構(gòu)體計(jì)算內(nèi)存占用問題解析
這篇文章主要介紹了C語言結(jié)構(gòu)體計(jì)算內(nèi)存占用問題解析,本文通過案例來解析了C語言計(jì)算結(jié)構(gòu)體內(nèi)存的方式和方法,需要的朋友可以參考下2021-07-07Qt開發(fā)之使用socket實(shí)現(xiàn)遠(yuǎn)程控制
本篇文章將會(huì)介紹下位機(jī)通過心跳包和上位機(jī)之間進(jìn)行數(shù)據(jù)交互和遠(yuǎn)程功能控制的實(shí)現(xiàn)方法。文中的示例代碼講解詳細(xì),感興趣的可以了解一下2022-11-11深入剖析C++中的struct結(jié)構(gòu)體字節(jié)對(duì)齊
要求數(shù)據(jù)內(nèi)存的起始地址的值是某個(gè)數(shù)k的倍數(shù),這就是所謂的內(nèi)存對(duì)齊,本文就來深入剖析C++中的struct結(jié)構(gòu)體字節(jié)對(duì)齊,需要的朋友可以參考下2016-05-05C語言簡(jiǎn)明分析選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)的使用
C語言條件控制語句選擇結(jié)構(gòu),是屬于計(jì)算機(jī)的語言編輯,有在C語言條件控制中的語句選擇結(jié)構(gòu)的存在,即是C語言條件控制語句選擇結(jié)構(gòu),循環(huán)控制語句是一個(gè)基于C語言的編程語句,該語句主要有while循環(huán)語句、do-while循環(huán)語句和for循環(huán)語句來實(shí)現(xiàn)循環(huán)結(jié)構(gòu)2022-04-04