2

我正在为嵌入式设备(ESP32)将 C 代码库转换为 C++。在当前代码中重复的一件事是向 C 模块声明“回调”并在“用户”模块中实现它们的方法。

例如,Button 模块的当前 API 如下:

void btn_init(uint32_t gpio);

// callbacks
extern bool btn_on_change_isr(bool is_pressed, uint32_t timer_duration_s);
extern bool btn_on_timer_isr(uint32_t duration_s);

知道函数是extern默认编辑的,这只是一个标志,表明模块不是负责实现它们的人。此方法的主要优点是链接器在编译时捕获未实现的回调。

在过渡到 C++ 时,我想保持编译时检查回调实现的存在(我不需要动态调度),但也允许创建多个对象,所以我需要类。

虽然我是 CRTP 和基于策略的设计的新手,但我想我应该选择其中之一。或者可能是模板函子?这两者有什么区别?

我目前的想法如下:

template <typename Impl>
class Button
{
  public:
    Button(uint32_t gpio, Impl impl_ = Impl())
        : impl(impl_)
    {
        (void)gpio;
    }
    bool on_change_isr(bool is_pressed, uint32_t timer_duration_s)
    {
        return impl.on_change_isr(is_pressed, timer_duration_s);
    }
    bool on_timer_isr(uint32_t duration_s)
    {
        return impl.on_timer_isr(duration_s);
    }

  private:
    Impl impl;
};

实现代码在哪里:

class MyButton
{
public:
    bool on_change_isr(bool is_pressed, uint32_t timer_duration_s)
    {
       // implementation 
    }
    bool on_timer_isr(uint32_t duration_s)
    {
       // implementation 
    }
};

让我感到困扰的一件主要事情是我仍然希望将实现保留在cpp文件中而不是标题中。对于这个Button类,我想在一个cpp文件中实现构造函数。我怎样才能做到这一点?

总的来说,这有意义吗?有没有更好的方法来注入回调而不使用继承?

4

0 回答 0