【问题标题】:C++ Passing member function reference from a class instance to another class instanceC ++将成员函数引用从类实例传递到另一个类实例
【发布时间】:2019-05-12 13:47:31
【问题描述】:

我对 C++ 很陌生,我正在努力完成一个需要在不同类实例之间传输对回调方法的引用的项目。我知道这个主题对于 C++ 初学者来说是一个很常见的问题。我知道成员函数指针与“标准”函数指针不同,但我找不到任何解决我的具体问题的帖子(但可能是因为,鉴于我缺乏 C++ 经验,我不理解提供的答案)。

我尝试开发的系统是基于:

  • ControllerManager 类(单例)
  • 控制器基类
  • 从 Controller 类继承的一些特定 Controller 类(FanControllerLighController 等)

我想做的是从一个 FanController 实例调用 ControllerManager 类的 addCallback 方法。该方法将一个指向 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 类声明的方法。

我要实现的是一个系统,它允许特定控制器向 ControllerManager 提供其成员方法(在 Controller 类中不存在)的引用,以便它可以调用这些方法。

如果有人可以帮助我,我提前感谢他/她。

【问题讨论】:

    标签: c++ callback


    【解决方案1】:

    解决这个问题的现代方法是将方法的绑定隐藏在 lambda 中。

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

    【讨论】:

    • 您好弗兰克,感谢您的回答。我应该指定此代码在 ESP32 微控制器(Arduino 框架)上执行,并且似乎 st::function 在此平台上不可用。
    • 弗兰克,抱歉,我回复得太快了。我确实可以访问 并且您的解决方案就像一个魅力。非常感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    相关资源
    最近更新 更多