How to pass a method as callback to another class?

后端 未结 4 583
没有蜡笔的小新
没有蜡笔的小新 2021-01-26 01:10

I have a question regarding callbacks using tr1::function. I\'ve defined the following:

  class SomeClass {
    public:
      typedef std::tr1::function

        
相关标签:
4条回答
  • 2021-01-26 01:56

    the function void (*)(unsigned char*, int) is a free function, which is a different type from void (SomeOtherClass::*)(unsigned char*, int), thus the error. You need an object to call the latter, while the former is a free function.

    Look at the possible solutions listed in the Boost documentation

    Another possibility is that your SomeOtherClass::myCallback is private, so you do not have access to it.

    0 讨论(0)
  • 2021-01-26 01:58

    Member functions have an implicit first parameter, a this pointer so as to know which object to call the function on. Normally, it's hidden from you, but to bind a member function to std::function, you need to explicitly provide the class type in template parameter.

    #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);
    }
    

    Output: You called me?;

    0 讨论(0)
  • 2021-01-26 02:00

    Use templates:

    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;
    };
    

    Such like this. And use it:

    ...
    B<MyClass> b;
    b.SetCallBack(&b, &MyClass::MyFunction);
    ...
    
    0 讨论(0)
  • 2021-01-26 02:01

    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.

    0 讨论(0)
提交回复
热议问题