MFC中類的非靜態函式作為工作者執行緒函式的方法

2021-08-07 11:32:21 字數 3461 閱讀 7017

對於windows來說,所有的執行緒都是一樣的。但是mfc卻把執行緒區分為兩種型別:使用者介面執行緒(

user inte***ce thread

)和工作者執行緒(

worker thread

)。使用者介面執行緒可以建立視窗並處理傳送給這些視窗的訊息。工作者執行緒執行後台任務,因其不接收使用者的直接輸入,所以不需要視窗和訊息迴圈。

通過createthread()函式可以建立工作者執行緒。該函式的第三個引數是工作者執行緒對應的函式。但是對於工作者執行緒對應的函式必須有如下要求。

執行緒函式格式必須是

dword winapi threadproc(

lpvoid lpparameter

其中,函式引數lpparameter的型別是

lpvoid

,可以指向任意型別的資料。

執行緒函式必須是全域性的或者是類的靜態函式。類的工作者執行緒中一般都要用到該類的成員變數和成員函式,因為執行緒函式要求是類的靜態函式,則在該函式中用到類的成員變數和成員函式都要是靜態的。這樣定義該類中會含有大量的靜態成員。解決該問題的方式將將該類的指標作為執行緒函式的引數傳入到函式中,通過該指標來呼叫類的成員變數和成員函式。但是該方法又會導致類中包含大量的訪問許可權為public的成員,破壞了類的封裝性。

如果類的非靜態函式能夠作為工作者執行緒函式,這樣就避免了上述問題。本文將通過類模板和函式模板實現該功能。

乙個模板(template)就是乙個建立類或函式的藍圖或公式。通過該模板,可以建立多個針對不同型別的函式版本或類版本。

1.1定義方式

模板定義以關鍵字template開始,後面跟著乙個模板引數列表(

template parameter list

),這是乙個逗號分隔的乙個或多個模板引數的列表

(template parameter)

的列表,用小於號和大於號包圍起來。

1.2 使用方法

在模板名後面的尖括號中提供一些額外資訊來指定模板到底例項化成什麼樣的函式或類。例如,有如下定義的模板函式

templateint compare(const t& v1, const t& v2)

在呼叫該模板時,使用如下**

int result = compare(1, 2);
以上**的含義是將模板函式例項化為型別引數為int

的函式,即

int compare(const int& v1, const int& v2)

類模板的使用方法與函式模板相同。

通過兩個類模板和乙個函式模板將非靜態函式作為執行緒函式

使用。其中,兩個類模板分別是繫結類模板和執行緒類模板,函式模板是建立執行緒模板,如圖1所示。

繫結類模板的主要作用是將類和其非靜態函式進行繫結。

templateclass xbind1

xreturn run()

};

其中,模板引數列表中的xclass

表示指定的類;

xreturn

表示類的非靜態成員函式的返回值;在

xbind1

這個模板類中,通過

typedef

定義了函式指標

typedef xreturn(xclass::* callfunc)();
本行**的含義是,將callfunc

型別定義為

xclass

類的成員函式的指標,該成員函式的返回值是

xreturn

,引數是

void

。之後,定義了模板類的兩個成員變數,m_callfunc和

m_pthis

,分別表示類的非靜態成員函式的指標和類例項的指標;在模板類的建構函式中分別對這兩個變數進行賦值;而該類的成員函式

run()

則執行類的某個例項的成員函式。

執行緒類模板的主要作用是定義乙個static成員函式,該成員函式作為

createthread()

函式建立的工作者執行緒函式,在該函式中呼叫繫結類

xbind

的run()

函式。

templateclass xthread1

};

其中,thread()

函式是該類的靜態成員函式,其格式與「

0.1

執行緒函式格式」中提到的函式格式相同。

thread()

函式的引數是

xbind1

類的指標,通過該指標呼叫

xbind1

類的run()

。建立執行緒函式模板的作用是通過createthread()函式建立執行緒。

templateinline handle startthread(xclass* pthis, xreturn(xclass::* pfn)())

其中,inline

表示該函式為內聯函式;該函式的兩個引數分別表示類的指標和類非靜態成員函式的指標;在該函式中,首先通過

newxbind1

類的物件,之後通過

createthread()

函式建立工作者執行緒,該執行緒的函式是

xthread1

類的靜態函式

thread

,其引數是

xbind1

類的物件。

這樣,通過執行緒函式模板startthread()就建立了新執行緒,在該執行緒中呼叫

xthread1

的thread()

函式,最終呼叫了指定類的某個例項的成員函式,即類的非靜態成員函式。

以下為完整**,在名為「threadtemplate.h」中的檔案中有如下**

#pragma once

namespace threadtemplate

xreturn run()

};templateclass xthread1

};templateinline handle startthread(xclass* pthis, xreturn(xclass::* pfn)())

}

在cnb_socket_clientdlg.cpp原始檔中包含該標頭檔案,並且建立cnb_socket_clientdlg類的非靜態成員函式threadtest()的執行緒

dword cnb_socket_clientdlg::threadtest()

return 0;

}

threadtemplate::startthread(this, &cnb_socket_clientdlg::threadtest);

靜態函式與非靜態函式的區別

靜態成員函式和非靜態成員函式的根本區別在於有無this指標。非靜態函式由物件名或者物件指標 呼叫,呼叫時編譯器會向函式傳遞this指標 靜態成員函式則由類名 或者物件名呼叫 非靜態函式中有this指標,靜態函式中沒有this指標,不能訪問物件的成員函式,成員函式有this指標,const修飾this...

靜態函式和非靜態函式的區別(靜態方法和非靜態方法)

首先,靜態函式 只有當程式結束的時候才從記憶體消失,生命週期長。而非靜態則是動態載入到記憶體,不需要的時候就從記憶體消失。而呼叫類中的靜態函式,無需建立物件就可以呼叫了,因為當類初始化的時候,就已經載入了靜態函式,所以靜態函式要比物件載入的早,物件只有被建立的時候才會在堆記憶體中建立空間。另外,靜態...

89 類的靜態函式

示例 1 include 2 include 3 include 4 using namespace std 56 類實現靜態函式管理靜態資料 7class myclass821 void go 2225 26void show 2730 31static void show2 int data 3...