2011-12-17 101 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