如何将一个方法作为回调传递给另一个类?

时间:2012-05-10 15:17:03

标签: c++ callback

我对使用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 个答案:

答案 0 :(得分: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?;

答案 1 :(得分:1)

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

查看Boost documentation

中列出的可能解决方案

另一种可能性是您的SomeOtherClass::myCallback是私有的,因此您无法访问它。

答案 2 :(得分:1)

为什么所有这些复杂的笨蛋?

为什么不这样创建一个类(例如)

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

然后只创建继承此类的类(并重新定义方法RunMouseOverCallback

然后注册功能只需要

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

register方法只调用方法,对象将拥有它所需要的一切。

似乎有点简单。让编译器使用指向函数等的指针来完成工作。

答案 3 :(得分: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);
...