2011-01-12 117 views
5

正如標題所示。 以下是我的代碼框架。在C++中運行類成員函數的線程

class CLASS 
{ 
public: 
    void A(); 
private: 
    DWORD WINAPI B(LPVOID); 
}; 

void CLASS::A() 
{ 
    DWORD (WINAPI CLASS::*thread)(LPVOID) = &CLASS::B; 
    ... 
    CreateThread(NULL, 0, thread, &arg, 0, NULL); 
    ... 
} 

函數B需要CLASS的成員變量。
但我編譯這個時有錯誤代碼。
這是「無法將參數3從'DWORD(__stdcall CLASS :: *)(LPVOID)'轉換爲'LPTHREAD_START_ROUTINE'」或類似的東西。
我不知道它在英語環境中是否一樣。

有人可以幫忙嗎?

回答

3

你必須使該成員功能static

這裏的問題是,每個非靜態成員函數都有一個隱含的this參數,這實際上是編譯器試圖告訴你的 - 你的nin-static成員函數的簽名與你期望的不同。

另請參閱this answer to a closely related question

+3

和運算開始前得到任何聰明的想法 - 非靜態類成員函數指針是*怪異*。不僅調用約定與簡單的`func(classname * this,...)`不同,_pointer representation_很奇怪 - 在某些情況下,類成員函數指針最終可能是普通函數指針的2倍,所以甚至不考慮迫使演員:) – bdonlan 2011-01-12 08:40:05

10

如果是成員函數,則必須將回調函數定義爲static函數!


更好的設計:定義一個可重用的類!

從我previous answer:(帶小的修改)

更妙的是定義與純虛函數run()一個可重用的由衍生線程類實現。這是應該如何來設計:

//runnable is reusable class. All thread classes must derive from it! 
class runnable 
{ 
public: 
    virtual ~runnable() {} 
    static DWORD WINAPI run_thread(LPVOID args) 
    { 
     runnable *prunnable = static_cast<runnable*>(args); 
     return prunnable->run(); 
    } 
protected: 
    virtual DWORD run() = 0; //derived class must implement this! 
}; 

class Thread : public runnable //derived from runnable! 
{ 
public: 
    void newthread() 
    { 
     CreateThread(NULL, 0, &runnable::run_thread, this, 0, NULL); 
    } 
protected: 
    DWORD run() //implementing the virtual function! 
    { 
     /*.....your thread execution code.....*/ 
    } 
} 
+0

我會使用模板,而不是運行時繼承。但總體思路是正確的。 – Puppy 2011-01-12 09:18:48

+0

@DeadMG:你的意思是CRTP? – Nawaz 2011-01-12 09:30:17

11

嚴重的是,使用std ::線程(或升壓::線程,如果你的編譯器不支持它尚未):

class CLASS 
{ 
public: 
    void A(); 
private: 
    void B(your args go here); 
}; 

void CLASS::A() 
{ 
    boost::thread(&CLASS::B, this, your args go here); 
}