如何在没有动态分配的情况下创建模板化对象数组

How to create array of templated objects without dynamic allocation

我一直在用 C++ 编程语言为 SPI I/O 扩展器开发软件驱动程序。我决定以这种方式 I/O 扩展器中的寄存器建模

class Register
{
  public:

    virtual bool read(void) = 0;
    virtual bool write(uint8_t data) = 0;
    virtual uint8_t getData(void) = 0;
    virtual uint8_t getAddress(void) = 0;

};

template <class T, uint8_t address>
class TypedRegister : public Register
{
  public:

    TypedRegister::TypedRegister() : reg_address(address){}
    bool read(void);
    bool write(uint8_t data);
    uint8_t getData(void);
    uint8_t getAddress(void);
    
  private:

    const uint8_t reg_address;
    T data;

};

将 I/O 扩展器中的所有寄存器放在一个数组中对我来说会很方便。问题是我无法以这种方式定义数组以避免内存的动态分配。数组定义

static constexpr uint8_t no_regs_in_expander = 18;
Register register_map[no_regs_in_expander];

不起作用,因为 Register 是抽象的 class 所以唯一的一种可能性是以这种方式定义数组

static constexpr uint8_t no_regs_in_expander = 18;
Register* register_map[no_regs_in_expander];

但这意味着我需要通过 new 运算符创建各个寄存器的实例,这在我的平台上是被禁止的。是否有任何可能性如何实现所有寄存器都可以在一个数组中并且实例是静态分配的状态?预先感谢您的建议。

多态方法分派仅在通过 pointer/reference 对对象调用虚方法时才起作用。您不需要 new 来创建指向对象的指针。但是,由于您没有可用的 new,在这种情况下(假设您的 I/O 寄存器使用不同的模板参数值),您唯一的选择是首先单独声明对象,然后您可以将指针存储到数组中的每个对象,例如:

TypedRegister<...> reg1;
TypedRegister<...> reg2;
TypedRegister<...> reg3;
...

static constexpr uint8_t no_regs_in_expander = 18;
Register* register_map[no_regs_in_expander];
register_map[0] = &reg1;
register_map[1] = &reg2;
register_map[2] = &reg3;
...

动态多态与动态内存分配无关。您可以拥有一些派生 class 的静态分配对象,并将其地址分配给指向基的指针。在您的情况下,它可能如下所示:

Register* register_map[2];

TypedRegister<int, 0> obj1;
TypedRegister<long, 1> obj2;

register_map[0] = &obj1;
register_map[1] = &obj2;

for (ptr : register_map)
  ptr->write(0);