错误:类型'void *(Thread ::)(void *)'的参数与'void *(*)(void *)'不匹配

时间:2013-04-17 00:53:46

标签: c++ pthreads

我正在使用pthread为我自己实现线程类。所以,我创建了Thread类,如下所示:

class Thread
{
public:
  Thread()
  {
  }

  virtual void* run(void *params) = 0;

  void start(void *params)
  {
    pthread_create (&threadId, 0, run, params);
    pthread_join (threadId, 0);
  }

private:
  pthread_t threadId;
};

实现这个类并重写virtual run函数后,我编译了这个项目。但是error: argument of type ‘void* (Thread::)(void*)’ does not match ‘void* (*)(void*)’发生了。我的代码出了什么问题?

提前致谢:)

3 个答案:

答案 0 :(得分:3)

正是编译器告诉你的内容。

pthread_create期待一个带签名的函数:

void* (*)(void*)

哪个是函数指针。

但是,您提供的是此签名:

void* (Thread::)(void*)

不是函数指针,而是指向成员函数的指针。有一点不同:指向成员函数的指针需要一个对象的实例才能正常工作(这里需要一个Thread实例)。

通常的解决方案是使你的函数run static:它不再是一个成员函数 - 它不再需要一个Thread实例才能正常工作,而你可以将当前实例作为pthread_create的最后一个参数传递,以便在线程启动后对其执行操作。 您只需要在类本身中保存参数。

public:
 void start(void *params)
 {
  this->my_thread_params = params;
  pthread_create (&threadId, 0, run, static_cast<void*>(this));
 }

private:
  static void *run(void *my_object)
  {
    // here, my_object already contains the params you passed to the function start
    static_cast<Thread*>(my_object)->my_member_function();
  }

答案 1 :(得分:2)

错误消息告诉您指向Thread中的成员函数的指针,该成员函数获取并返回void*void* (Thread::*)(void*))不能转换为函数获取和返回的指针同样的void*

虽然成员函数的声明可能看起来与您需要的类型相似,但是this类型的隐式Thread指针需要在对{{1}的任何调用时注入}

答案 2 :(得分:2)

pthread_create是一个C函数,对C ++成员函数一无所知。您需要为其提供静态或非成员函数,并通过Thread的最终参数将指针传递给pthread_create对象;类似的东西:

class Thread
{
    virtual void* run(void *params) = 0;

    void start(void * params)
    {
        this->params = params;
        pthread_create(&threadId, 0, &Thread::static_run, this);
    }

    static void * static_run(void * void_this)
    {
         Thread * thread_this = static_cast<Thread*>(void_this);
         return thread_this->run(thread_this->params);
    }

private:
    pthread_t threadId;
    void *params;
};

当然在现代C ++中,这更为直白:

std::thread thread;

void start(void * params)
{
    thread = std::thread([this]{run(params);});
}

(虽然你当然不应该使用void*来传递你的参数,并且可能没有充分的理由将线程首先包装在一个类中。)