c++ - C++ 中的匿名内部类(Java 风格的监听器)

标签 c++ interface arduino listener anonymous-inner-class

我的 C/C++ 技能有点生疏,过去几年我主要从事 Java 工作。现在我刚开始玩 Arduino,做了一个简单的按钮类。我想添加一个事件监听器,所以我做了这样的事情:

class MyButton{
  public:
      MyButton(byte pin);
      bool isPressed();
      bool wasToggled();
      bool wasPressed();
      void eventLoop();
      inline void setListener(MyButtonListener* listener) { _listener = listener; }

  private:
      byte _pin;
      boolean _lastToggledState = false;
      MyButtonListener* _listener;
};



class MyButtonListener{
    public: 
        virtual void onPressed() = 0;

    private:
};

eventLoop() 方法(旨在从 Arduino loop() 函数调用)调用 onPressed()监听器类中的方法:

void MyButton::eventLoop(){
    if( wasPressed() && _listener ){
        _listener->onPressed();
    }
}

到目前为止,一切都还好。但我无法弄清楚如何在 Arduino 主文件中实际分配和使用监听器。来自 Java,我习惯于做类似的事情

myBtn.setListener( new MyButtonListener(){
    void onPressed(){
        Serial.println("Pressed");
        toggleLed(); // toggleLed() is a method in the main Arduino file
    }
});

我让它以一种非常复杂的方式工作,通过声明一个将 toggleLed() 方法作为参数的新类(因为它不能从新类中访问,否则):

class BtnListener : public MyButtonListener{
    public:
        BtnListener(void* toggleFunction) : _toggleFunction(toggleFunction){ };

    private:
        void (*_toggleFunction)();

        void onPressed(){
            Serial.println("Pressed");
            _toggleFunction();
        };
};



myBtn.setListener( new BtnListener(toggleLed) );

在 C++ 中肯定有更方便的方法来做这样的事情吗?对于一个听众来说这是可行的(但很丑陋)——我什至无法想象拥有 10 个按钮都需要不同的听众实现的恐怖......

最佳答案

在您的情况下,一种或最简单的方法是将监听器存储为 std::function<void()>并且根本没有一个实际的类来模拟按钮监听器(如果你真的想封装它,你仍然可以拥有它,但这不是必需的)。然后使用 lambda 函数调用 setListener,如下所示:

myBtn.setListener( [this]{
        Serial.println("Pressed");
        toggleLed(); // toggleLed() is a method in the main Arduino file
    });

关于c++ - C++ 中的匿名内部类(Java 风格的监听器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53225192/

相关文章:

c - 使用内核模块读写 Arduino 串口

c - 范围退出时未释放字符串数组

c# - 使用 printf 打印字符串值

c# - 在 C# 中,如果我的对象支持该接口(interface),我如何检查 T 是否属于 IInterface 类型并强制转换为该类型?

java - 使用抽象类实现接口(interface)时要声明什么(不)?

objective-c - 将 ivar 放在类扩展中有什么问题?

c++ - 获取基类指针的派生类

c++ - 如何在Visual Studio中导入和使用外部库

c++ - 为什么 vector::push_back 有两个重载?

c++ - 在 Arduino 上存储产品数据库