Вопрос по c++, callback – Как передать метод в качестве обратного вызова в другой класс?

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

  }

Теперь я хочу зарегистрировать свою функцию «myCallback». в качестве обратного вызова в классе «SomeClass» с использованием метода «registerCallback». Тем не менее, это не работает. Я посмотрел документацию по функции, и кажется законным использование (членов) методов класса для обратных вызовов. Я ошибся?

Заранее спасибо!

std::function ничем не отличается отthis problem когда дело доходит до обратных вызовов Flexo♦
Определить «не работает». Использование классаCallback по значению здесь выглядит немного подозрительно для меня. Steve Townsend

Ваш Ответ

4   ответа
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);
...
Спасибо Максиму за ответ.
Добро пожаловать на Stackoverflow :) Дополнительные пояснения должны быть добавлены в ваш пост. Не пишите код без контекста: объясните, что вы делаете.
1

Почему все это так сложно?

Почему бы не создать класс таким образом (например)

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

Затем просто создайте классы, которые наследуют этот класс (и переопределите методRunMouseOverCallback)

Тогда функция Register просто должна быть

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

Метод register просто вызовет метод, и у объекта будет все, что ему нужно.

Кажется, немного проще. Пусть компилятор выполняет работу с указателями на функции и т. Д.

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 заSSCCE
1

функцияvoid (*)(unsigned char*, int) это свободная функция, которая отличается отvoid (SomeOtherClass::*)(unsigned char*, int)Таким образом, ошибка. Вам нужен объект для вызова последнего, тогда как первый является бесплатной функцией.

Посмотрите на возможные решения, перечисленные вПовысить документацию

Другая возможность заключается в том, что вашSomeOtherClass::myCallback является частным, поэтому у вас нет доступа к нему.

Похожие вопросы