0

tr1::functionを使用したコールバックについて質問があります。私は以下を定義しました:

  class SomeClass {
    public:
      typedef std::tr1::function<void(unsigned char*, int)> Callback;
      void registerCallback(Callback);
    private:
      Callback callback;
  }

別のクラスを定義しました:

  class SomeOtherClass {
      void myCallback(unsigned char*, int);

  }

次に、メソッド「registerCallback」を使用して、関数「myCallback」をクラス「SomeClass」のコールバックとして登録します。ただし、動作していません。関数のブーストドキュメントを見てきましたが、コールバックにクラスの(メンバー)メソッドを使用するのは合法のようです。私が間違っている?

前もって感謝します!

4

4 に答える 4

4

メンバー関数には、this関数を呼び出すオブジェクトを知るための暗黙的な最初のパラメーターであるポインターがあります。通常は隠されていますが、メンバ関数を std::function にバインドするには、テンプレート パラメータでクラス タイプを明示的に指定する必要があります。

#include <functional>
#include <iostream>

struct Callback_t {
    void myCallback(int)
    {
        std::cout << "You called me?";
    }
};

class SomeClass {
public:
    SomeClass() : callback() { }
    typedef std::function<void(Callback_t*, int)> Callback;
                           //  ^^^^^^^^^^^

    void registerCallback(const Callback& c)
    {
        callback = c;
    }

    void callOn(Callback_t* p)
    {
        callback(p, 42);
    }
private:
    Callback callback;
};

int main()
{
    SomeClass sc;
    sc.registerCallback(&Callback_t::myCallback);

    Callback_t cb; // we need an instance of Callback_t to call a member on
    sc.callOn(&cb);
}

出力: You called me?;

于 2012-05-10T16:06:32.943 に答える
1

なぜこのすべての複雑なマンボジャンボ?

このようにクラスを作成してみませんか(たとえば)

Class MouseOverEventCallBack
{
   public:
      virtual void RunMouseOverCallback() = 0;
};

次に、このクラスを継承するクラスを作成します(そしてメソッドを再定義しますRunMouseOverCallback

次に、登録機能は

void registerCallback(MouseOverEventCallBack *callbackObject); // possible could use a reference

registerメソッドはメソッドを呼び出すだけで、オブジェクトには必要なものがすべて含まれます。

少し簡単なようです。関数などへのポインターを使用してコンパイラーに作業を任せます。

于 2012-05-10T15:29:54.900 に答える
1

関数void (*)(unsigned char*, int)はフリー関数であり、 とはタイプが異なるvoid (SomeOtherClass::*)(unsigned char*, int)ため、エラーが発生します。後者を呼び出すにはオブジェクトが必要ですが、前者は自由な関数です。

Boostのドキュメントにリストされている可能な解決策を見てください

もう 1 つの可能性は、あなたSomeOtherClass::myCallbackが非公開であるため、アクセスできないことです。

于 2012-05-10T15:21:16.910 に答える
0

テンプレートを使用する:

template <class T>
class B
{
  public:
    typedef void (T::*TCallBackFunction)(void);   
    void SetCallBack(T* pCallBackClass, TCallBackFunction pCallBackFunction)
    {
      if(pCallBackFunction && pCallBackClass)
      {
        m_pCallBackFunction = pCallBackFunction;
        m_pCallBackClass = pCallBackClass;
      }
    }
    void StartCallBackFunction()
    {
      (pCallBackClass->(*m_pCallBackFunction))();
    }
  private:
    TCallBackFunction m_pCallBackFunction;
    T* m_pCallBackClass;
};

このような。そしてそれを使用します:

...
B<MyClass> b;
b.SetCallBack(&b, &MyClass::MyFunction);
...
于 2013-08-12T12:34:40.563 に答える