C ++ Передача ссылки на функцию-член из экземпляра класса в другой экземпляр класса - PullRequest
2 голосов
/ 12 мая 2019

Я очень новичок в C ++, и я борюсь за проект, где мне нужно передать ссылку на метод обратного вызова между различными экземплярами класса. Я знаю, что эта тема является довольно распространенной проблемой для начинающих C ++. Я понимаю, что указатели на функции-члены отличаются от «стандартных» функций, но я не могу найти ни одного сообщения, которое бы касалось моей конкретной проблемы (но может быть так, потому что, учитывая мой недостаток опыта в C ++, я не понимаю предоставленные ответы ).

Система, которую я пытаюсь разработать, основана на:

  • A ControllerManager класс (который является Singleton)
  • A Контроллер Базовый класс
  • Некоторые конкретные классы контроллеров ( FanController , LighController и т. Д.), Которые наследуются от класса контроллеров

Я хотел бы сделать, скажем, экземпляр FanController для вызова addCallback метода ControllerManager класса. Этот метод будет принимать в качестве параметра указатель на любой открытый метод FanController, чтобы ControllerManager мог выполнить обратный вызов этого метода позже (я должен указать, что ControllerManager включает определение класса Controller, но ничего не знает о Класс FanController)

Пока я не нашел никакого рабочего решения, единственное, что мне удалось получить, - это очень плохой обходной путь (для простоты указаны только соответствующие методы):

class Controller {

public:
    virtual void callback();
};


class FanController:Controller {

public:
    virtual void callback();
};


class ControllerManager
{
private:
    static ControllerManager *_instance;
    Controller *_controller;

public:

    void addCallback(Controller * controller)
    {
        _controller = controller;
    }

    static void periodicCallback()
    {
       _instance->_controller->callback();
    }
};

Во время выполнения экземпляр FanController предоставляет ссылку на свой собственный объект ControllerManager:

ControllerManager::getInstance()->addController(this);

и ControllerManager может вызвать метод обратного вызова экземпляра FanController:

 _instance->_controller->callback();

Этот обходной путь очень ограничен, поскольку он допускает только вызовы методов, объявленных родительским Controller классом.

То, что я хотел бы реализовать, - это система, которая позволяет специфическим контроллерам предоставлять ссылки на свои методы-члены (которых нет в классе Controller) на ControllerManager, чтобы он мог выполнять вызовы этих методов.

Если кто-то может мне помочь, я заранее благодарю его / ее.

1 Ответ

0 голосов
/ 12 мая 2019

Современный способ решения этой проблемы заключается в сжатии привязки метода к лямбде.

#include <functional>
#include <vector>


class Controller {
  std::vector<std::function<void()>> callbacks_;

public: 
  void addCallback(std::function<void()> cb) {
      callbacks_.push_back(std::move(cb));
  }

  void periodicCallback() {
     for(const auto& cb : callbacks_) {
       cb();
     }
  }
};


class Fan {
public:
  void whatever() {}

  void register_in_controller(Controller* tgt) {
    tgt->addCallback([this]{whatever();});
  }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...