在單獨執行緒中執行物件成員函式

2022-02-06 16:06:59 字數 1560 閱讀 6467

問題的提出:

實際上所有執行緒都是用來處理c函式的,而不是c++類成員函式。標準庫中提供乙個api函式,這個函式以**函式指標作為執行緒的執行**並在單獨的執行緒中呼叫**函式。問題是在這樣的執行緒庫中不能建立執行物件成員函式的執行緒;只能使用普通的函式。因此,下列**是失敗的:

// 啟動執行緒庫函式的執行緒

int thr_create (void (*pf)(), void* prm, thread_t* pth);

#include "class1.h"

int func (void *param )

函式thr_create()需要**函式的位址,void* 作為位址引數被傳遞到**函式,同時傳遞的引數還有thread_t變數的指標(有關**函式和函式指標的概念參見vc知識庫中另外的文章)。

上面的**之所以編譯失敗是因為傳遞到thr_create()的第乙個引數是類class1的成員函式指標,而不是普通函式指標。從概念上講,普通函式和類成員函式是兩個完全不同的事情。即使進行強制型別轉換也不行。那麼如何解決這個問題呢?

方法一:使用靜態成員函式

第乙個解決方法是使**成員函式為靜態。因為靜態成員函式不帶隱含式引數「this」。因此,可以將其引數中的位址當作是普通函式的指標來使用。如果要從靜態成員函式中訪問物件的資料成員,顯式傳入物件的位址即可。例如:

class hack

;void hack::func(hack * pthis)

這個方法在大多數情形下都能行得通,但有時候成員函式不能宣告為靜態,也就是說成員函式是虛函式或者正在使用不能修改的第三方類。遇到這種情況時,用方法一解決問題就比較難了。

方法二:處理非靜態成員函式

假設需要在單獨的執行緒中呼叫類hack的非靜態成員函式func2()。不用直接傳遞成員函式的位址到thr_create(),宣告乙個帶 void* 引數的普通函式intermediary(void*),然後呼叫它:

void intermediary(void*);

接著建立乙個結構,結構定義如下:

struct a

;建立乙個結構例項,用希望的物件位址和成員函式位址填充結構(有關詳細的成員函式指標內容請參見vc知識庫中的其它文章)。

a a; // 結構例項

hack h; // 建立物件

//填充結構

a.p = & h; 

a.pmf = &hack::func2; // 取成員函式位址

現在回過頭來實現intermediary()函式:

void intermediary(void* ptr)

最後將intermediary()的位址傳遞到thr_create():

thr_create (intermediary, (void*) &a, &t1 );

thr_create()呼叫函式intermediary()並將a的位址傳遞給它。intermediary()再從其指標引數中展開結構a並呼叫希望的成員函式。這種間接方式的處理可以安全地在單獨執行緒中啟動成員函式,即便是執行緒庫不支援成員函式。如果需要呼叫不同類的不同成員函式,可以將結構a轉換成類模板,將函式intermediary()轉換成函式模板。從而編譯器便會自動產生大多數樣板檔案**。

在單獨執行緒中執行物件成員函式

問題的提出 實際上所有執行緒都是用來處理c函式的,而不是c 類成員函式。標準庫中提供乙個api函式,這個函式以 函式指標作為執行緒的執行 並在單獨的執行緒中呼叫 函式。問題是在這樣的執行緒庫中不能建立執行物件成員函式的執行緒 只能使用普通的函式。因此,下列 是失敗的 啟動執行緒庫函式的執行緒 int...

Qt多執行緒程式設計中的物件執行緒與函式執行執行緒

為了更清楚的理解這些問題,在此特編了個小例子說明一下。首先定義乙個從qobject繼承的類someobject,包含乙個訊號somesignal和乙個成員函式callemitsignal,此函式用於傳送前面的somesignal訊號。定義如下 define object class class so...

Qt多執行緒程式設計中的物件執行緒與函式執行執行緒

2017 05 10 16 40 25人閱讀收藏 編輯刪除 qt 24 作者同類文章x 而對於伺服器來說,多執行緒的這個特性太有用了,因為多執行緒使得伺服器可能同時響應多個客戶端的請求,所以現在伺服器大多採用多執行緒,所以才會造成我開始的誤解。不管是多執行緒,還是伺服器,qt中已經封裝好了特定的類,...