Как реализовать обратные вызовы с интерфейсом

У меня есть класс, который нуждается в большем количестве обратных вызовов. Я пытаюсь реализовать их с помощью интерфейса:

class CallbacksInterface
{
public:
     virtual bool mycallback1() = 0;
     virtual bool mycallback2() = 0;
     virtual bool mycallback3() = 0;
};

Class BusImplementation{
public:
    addRequest(bool (CallbacksInterface::*callback)());

}

Обратный вызов является параметром для метода addRequest() и определяется как указатель на метод интерфейса. Поэтому я хочу добавить запрос..

//class with callbacks
class Main:CallbacksInterface{
public:
      bool mycallback1(){..};
      bool mycallback2(){..};
      bool mycallback3(){..};
      //.. 
}

BusImplemantation bus;
Main main;   

bus.addRequest(main.mycallback1);          
bus.addRequest(main.mycallback2);
bus.addRequest(main.mycallback3);

Но я не могу передать обратный вызов в мой класс BusImplemantation

error: argument of type 'bool (Main::)()' does not match 'bool (CallbacksInterface::*)()'

Я думаю, что есть решение с помощью шаблонов, но я программирую встроенные устройства, и мой компилятор ограничен.

2 ответа

Решение

Более простой подход заключается в определении единственного типа интерфейса, представляющего функцию:

struct ICallback
{
  virtual bool operator()() const = 0;
};

и реализовать его столько раз, сколько необходимо:

struct Foo : ICallback
{
  virtual bool operator()() const { return true;}
};

struct Bar : ICallback
{
  virtual bool operator()() const { return false;}
};

тогда ваша реализация шины может принимать интерфейсы обратного вызова:

class BusImplemantation{
public:
    void addRequest(const ICallback* callback) { .... }
};

затем

BusImplemantation bus;
Foo foo;  // can be called: bool b = foo();
Bar bar;   // can be called: bool b = bar();

bus.addRequest(&foo);          
bus.addRequest(&bar);

Вы также можете исследовать, используя std:: function и вообще избегая общего интерфейса.

Я также настоятельно рекомендую перейти с абстрактным интерфейсом. Однако, если вы действительно хотите оригинальный подход по какой-то причине, вам нужно что-то вроде этого:

void addRequest(bool (CallbacksInterface::*callback)(), CallbacksInterface* pTarget) {...}
...
bus.addRequest(&CallbacksInterface::mycallback1, &main); 
// ! Not &Main::mycallback1 - that wouldn't compile
...
// calling a callback
(pTarget->*callback)();
Другие вопросы по тегам