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'的回调。但是,它不起作用。我查看了有关该函数的 boost 文档,使用类的(成员)方法进行回调似乎是合法的。我错了吗?

提前致谢!

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

Why all this complicated mumbo-jumbo?

Why not create a class as thus (for example)

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

Then just create classes that inherit this class (and redefine the method RunMouseOverCallback)

Then Register function just needs to be

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

The register method will just call the method and the object will have all that it needs.

Seems a bit simpler. Let the compiler do the work with pointers to functions etc.

于 2012-05-10T15:29:54.900 回答
1

该函数void (*)(unsigned char*, int)是一个自由函数,它与 的类型不同void (SomeOtherClass::*)(unsigned char*, int),因此出现错误。你需要一个对象来调用后者,而前者是一个自由函数。

查看Boost 文档中列出的可能解决方案

另一种可能性是您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 回答