2

重複の可能性:
メンバー関数の関数ポインター

問題があります。クラスでは、このメソッドがあります。virtual void start(void *(*ptr)(void*), void *);
別のメソッドでは、このメソッドでstartを呼び出します:void *Room::run(void *p)

だから私はこれをやろうとしました:thread->start(&Room::run, 0);しかしコンパイラはそれを望んでいません:cannot convert parameter 1 from 'void *(__thiscall Room::* )(void *)' to 'void *(__cdecl *)(void *)'

どうすれば解決できますか?テンプレート?または、より明白な解決策はありますか?
ありがとうございました !

PS:正確には、スレッドを作成するために必要です(http://linux.die.net/man/3/pthread_create)。

4

2 に答える 2

3

C ++では、(独立した)関数へのポインターとメソッドへのポインターは完全に異なる獣であり、混合することはできません。

関数へのポインタを必要とするAPIにメンバーへのポインタ関数を渡したい場合、一般的な解決策は小さなラッパー関数を使用することです。

class Room {
public:
  void run();
  // other members omitted

  // wrapper function
  static void* run_wrapper(void* p)
  {
    static_cast<Room*>(p)->run();
    return NULL;
  }
};

そして、あなたはそれを次のように使用します:

thread->start(Room::run_wrapper, myRoomPointer);
于 2013-01-15T13:21:25.430 に答える
0

void *c ++および場合によってはcでもサイズが異なる可能性があるため、関数ポインターをポインターにキャストしないことを強くお勧めします。

全体として、ソリューションはあまりc++ではありません。確かに、acライブラリを使用すると少し注意が必要になります。現在のプロジェクトで使用している方法は次のとおりです。-

class ThreadBase
{
public:
  ThreadBase ()
  {
  }

  virtual ~ThreadBase ()
  {
    // TODO - inform thread to stop, using a message or a signal or something
    // and then wait for the thread to terminate
    void
      *return_value = 0;

    pthread_join (m_thread_handle, &return_value);
  }

  void Run ()
  {
    if (pthread_create (&m_thread_handle, 0, ThreadFunction, this))
    {
      // error - throw an exception or something
    }
  }

private:
  static void *ThreadFunction (void *param)
  {
    ThreadBase
      *thread = static_cast <ThreadBase *> (param);

    thread->Main ();

    return 0;
  }

  virtual void Main () = 0;

private:
  pthread_t
    m_thread_handle;
};

次に、ThreadBaseから実装固有のバージョンを派生させます。

class SomeThread : public ThreadBase
{
private:
  void Main ()
  {
    // do something
  }
};

Main終了コードを返し、それをスレッドから返すように変更することもできます。Mainそして、それが無限ループにある場合(たとえば、ある種のメッセージを消費するリスナーである場合)に終了する方法が必要です。

于 2013-01-15T13:43:35.067 に答える