将指向成员函数的指针绑定到std :: pair并转换为void *

时间:2011-12-17 17:29:52

标签: c++

我有一个我正在尝试实现的小型Thread类的以下代码片段:

声明:

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 *并返回时并不是很好。是这样的情况(因为我不直接这样做)?

任何指针/建议都将受到高度赞赏。

谢谢! :)

1 个答案:

答案 0 :(得分:1)

这是segfaulting,因为在调用createThread函数之前,临时对std::pair<T*, void (T::*)()> p(arg,function);正在从范围上掉下来。

将对的副本存储在堆内存中并传递。 然后删除createThread函数中的副本。

修改

顺便说一下,使用std :: functions可能会更好地表示。完全相同的想法(代码甚至看起来相似),但不会强迫您重写代码以获取其他参数。请看pthread member function of a class with arguments