国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

在單獨線程中執(zhí)行對象成員函數(shù)

2019-11-17 05:13:47
字體:
供稿:網(wǎng)友
問題的提出:

  實際上所有線程都是用來處理C函數(shù)的,而不是C++類成員函數(shù)。標準庫中提供一個API函數(shù),這個函數(shù)以回調(diào)函數(shù)指針作為線程的執(zhí)行代碼并在單獨的線程中調(diào)用回調(diào)函數(shù)。問題是在這樣的線程庫中不能創(chuàng)建執(zhí)行對象成員函數(shù)的線程;只能使用普通的函數(shù)。因此,下列代碼是失敗的:

// 啟動線程庫函數(shù)的線程
int thr_create (void (*pf)(), void* PRm, thread_t* pth);#include "class1.h"int func (void *param )
{
thread_t t1;
// 下列調(diào)用導(dǎo)致編譯器錯誤: "Cannot convert ''void (class1::*)()'' to ''void (*)()''"
// 意思是不能轉(zhuǎn)換類型
return thr_create ( &class1::some_method, param, &t1);
}  函數(shù)thr_create()需要回調(diào)函數(shù)的地址,void* 作為地址參數(shù)被傳遞到回調(diào)函數(shù),同時傳遞的參數(shù)還有thread_t變量的指針(有關(guān)回調(diào)函數(shù)和函數(shù)指針的概念參見VC知識庫中另外的文章)?! ∩厦娴拇a之所以編譯失敗是因為傳遞到thr_create()的第一個參數(shù)是類class1的成員函數(shù)指針,而不是普通函數(shù)指針。從概念上講,普通函數(shù)和類成員函數(shù)是兩個完全不同的事情。即使進行強制類型轉(zhuǎn)換也不行。那么如何解決這個問題呢?  方法一:使用靜態(tài)成員函數(shù)  第一個解決方法是使回調(diào)成員函數(shù)為靜態(tài)。因為靜態(tài)成員函數(shù)不帶隱含式參數(shù)“this”。因此,可以將其參數(shù)中的地址當作是普通函數(shù)的指針來使用。假如要從靜態(tài)成員函數(shù)中訪問對象的數(shù)據(jù)成員,顯式傳入對象的地址即可。例如:class Hack
{
private:
int x;
public:
int get_x();
static void func(Hack * pthis); // 靜態(tài)成員函數(shù)
void func2(); // 非靜態(tài)成員函數(shù)
};void Hack::func(Hack * pthis)
{
int y = pthis->get_x(); // 訪問對象的數(shù)據(jù)成員
}  這個方法在大多數(shù)情形下都能行得通,但有時候成員函數(shù)不能聲明為靜態(tài),也就是說成員函數(shù)是虛函數(shù)或者正在使用不能修改的第三方類。碰到這種情況時,用方法一解決問題就比較難了?! 》椒ǘ禾幚矸庆o態(tài)成員函數(shù)  假設(shè)需要在單獨的線程中調(diào)用類Hack的非靜態(tài)成員函數(shù)func2()。不用直接傳遞成員函數(shù)的地址到thr_create(),聲明一個帶 void* 參數(shù)的普通函數(shù)intermediary(void*),然后調(diào)用它:void intermediary(void*);  接著創(chuàng)建一個結(jié)構(gòu),結(jié)構(gòu)定義如下:strUCt A
{
Hack * p; //類對象指針
void (Hack::*pmf)(); // 成員函數(shù)指針
};  創(chuàng)建一個結(jié)構(gòu)實例,用希望的對象地址和成員函數(shù)地址填充結(jié)構(gòu)(有關(guān)具體的成員函數(shù)指針內(nèi)容請參見VC知識庫中的其它文章)。A a; // 結(jié)構(gòu)實例
Hack h; // 創(chuàng)建對象
//填充結(jié)構(gòu)
a.p = & h;
a.pmf = &Hack::func2; // 取成員函數(shù)地址  現(xiàn)在回過頭來實現(xiàn)intermediary()函數(shù):void intermediary(void* ptr)
{
 A* pa=static_cast < A* > (ptr); // 強制轉(zhuǎn)換 p 為 A*
 Hack* ph=pa->p; // 從A中析取Hack對象地址
 void (Hack::*pmf)()=pa->pmf; // 析取 ptr 到成員函數(shù)
 (ph->*pmf)(); // 調(diào)用成員函數(shù)
}  最后將intermediary()的地址傳遞到thr_create():thr_create (intermediary, (void*) &a, &t1 );  thr_create()調(diào)用函數(shù)intermediary()并將A的地址傳遞給它。intermediary()再從其指針參數(shù)中展開結(jié)構(gòu)A并調(diào)用希望的成員函數(shù)。這種間接方式的處理可以安全地在單獨線程中啟動成員函數(shù),即便是線程庫不支持成員函數(shù)。假如需要調(diào)用不同類的不同成員函數(shù),可以將結(jié)構(gòu)A轉(zhuǎn)換成類模板,將函數(shù)intermediary()轉(zhuǎn)換成函數(shù)模板。從而編譯器便會自動產(chǎn)生大多數(shù)樣板文件代碼。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 个旧市| 泰州市| 故城县| 同心县| 汶上县| 双辽市| 铁力市| 井冈山市| 綦江县| 临洮县| 鹤峰县| 朔州市| 临湘市| 行唐县| 太和县| 乌海市| 永新县| 邵东县| 东乌| 积石山| 鲜城| 高雄市| 华池县| 文山县| 四川省| 辽阳县| 抚远县| 阳城县| 闽侯县| 阿拉善右旗| 疏勒县| 吴川市| 嫩江县| 哈尔滨市| 时尚| 静海县| 天气| 保亭| 合水县| 彭泽县| 和龙市|