2011-12-17 94 views
1

我有一個小Thread類我想實現的下面的代碼片段:綁定指針到成員函數到std ::對,鑄造到void *

聲明:

template <typename T> 
class Thread{ 
public: 
    Thread(T*, void (T::*)()); 
    void start(); 
private: 
    friend void* createThread(void*); 
    T* arg; //the object 
    void (T::*function)(); //the ptr to function in that object of type T 
    pthread_t thread; 
}; 

以下是定義的片段。

template <typename T> 
void* createThread(void *arg){ 
    //get back the pair.. 
    std::pair<T*, void (T::*)()>* p = (std::pair<T*, void (T::*)()>*)arg; 

    //open up the pair 
    T& t = *p->first; 
    void (T::*fn)() = p->second; 

    //TEST 
    Temp ttt; 
    ttt.a=100; 
    (ttt.*fn)(); //segfaults here.. 

    (t.*fn)(); //and even here 
} 

template <typename T> 
void Thread<T>::start(){ 
    //pair of pointer to object, and the pointer-to-member-function 
    std::pair<T*, void (T::*)()> p(arg,function); 
    pthread_create(&thread, NULL, createThread<T>, (void*)&p); 
} 

在上面的代碼中,Temp是一個帶有函數和字段'a'的類。我得到的線程運行以下代碼:

Temp t; 
t.a=11; 
Thread<Temp> tt(&t, &Temp::function); 

tt.start(); 

任何想法爲什麼代碼段錯誤?我記得指向成員函數的指針不能很好地執行void *和back。在這裏是這種情況嗎(因爲我沒有直接這樣做)?

任何指標/建議將不勝感激。

謝謝! :)

回答

1

它是segfaulting,因爲您的臨時配對std::pair<T*, void (T::*)()> p(arg,function);在您的createThread函數被調用之前已經脫離了範圍。

將您的配對副本存儲在堆內存中並傳遞該副本。 然後刪除createThread函數中的副本。

編輯

順便說一句,這可能會得到更好的使用std ::函數來表示。完全相同的想法(代碼甚至看起來相似),但不強制您重寫您的代碼以獲取更多參數。看看pthread member function of a class with arguments

+0

該死的,我怎麼能忽略它呢?我無法放棄這一點! :P 謝謝伊桑,謝謝! :) – user1103651 2011-12-17 17:49:34

+1

@ user1103651當我第一次嘗試將參數綁定到pthread_create時,我犯了完全相同的錯誤。每個人都有他們在C++中的段錯誤。 – Lalaland 2011-12-17 17:55:51