Warm tip: This article is reproduced from serverfault.com, please click

How to create array of templated objects without dynamic allocation

发布于 2020-12-02 16:34:43

I have been developing software driver for the SPI I/O expander in the C++ programming language. I have decided to model the registers in the I/O expander in this manner

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;

};

It would be convenient for me to have all the registers in the I/O expander in an array. The problem is that I am not able to define the array in such manner to avoid the dynamic allocation of memory. The array definition

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

does not work because the Register is abstract class so the only one possibility is to define the array in this manner

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

but it means that I need to create instances of the individual registers via new operator which is prohibited on my platform. Is there any posibility how to achieve a state where all the registers can be in one array and the instances are statically allocated? Thanks in advance for an advice.

Questioner
L3sek
Viewed
0
Daniel Langr 2020-12-03 00:57:18

Dynamic polymorphism is not related to dynamic memory allocations. You can have a statically allocated object of some derived class and assign its address to a pointer-to-base. In your case, it might look as follows:

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);