2021年1月18日星期一

Using statically allocated derived class objects to initialize an array of base class pointers

I have some classes designed to hold a pointer to some variables, and some other properties which are related to variables. Actually, I'm trying to design a CANopen stack for STM32 and I'm planning to use these classes to represent the object dictionary.

Here are the simplified versions of the classes:

class Object {  public:      constexpr Object(int index) : index{index} {}  private:      int index;  };    class Single : public Object {  public:      constexpr Single(int index, void* var, std::size_t size)      : Object{index}, ptr{var}, size{size} {}  private:      void* ptr;      std::size_t size;  };    class Array : public Object {  public:      constexpr Array(int index, void* var, std::size_t size, std::size_t length)      : Object{index}, ptr{var}, size{size}, length{length} {}  private:      void* ptr;      std::size_t size;      std::size_t length;  };  

And I wish to create an array of these objects. The code below compiles without problems:

int a {1}; // Single variable  float b[] {2.0, 3.0}; // Array    const Object* dictionary[] {      new Single(0x1000, &a, sizeof(int)),      new Array(0x1001, b, sizeof(float), std::size(b))  };  

The problem is, I try to avoid using heap (dynamic allocation) as much as possible. Usage of dynamic allocation in embedded systems is a debated subject, but my main concern is memory utilization: STM32 microcontrollers have a lot more flash ROM than they have RAM, so it's preferable to mark variables as const, so the linker can place them into ROM instead of RAM.

But when a modify the code as below, it doesn't compile:

const Object* dictionary[] {      &Single(0x1000, &a, sizeof(int)),      &Array(0x1001, b, sizeof(float), std::size(b))  };  

It gives error: taking address of rvalue error.

I can think of one solution:

const Single a_obj {0x1000, &a, sizeof(int)};  const Array b_obj {0x1001, b, sizeof(float), std::size(b)};    const Object* dictionary[] {      &a_obj,      &b_obj  };  

This works without problems, and places a_obj & b_obj into ROM. But I think it looks ugly. It forces me to define and maintain additional set of variables, and imagine what if you have maybe ~20 of them. Is there a cleaner way?

https://stackoverflow.com/questions/65772767/using-statically-allocated-derived-class-objects-to-initialize-an-array-of-base January 18, 2021 at 06:30PM

没有评论:

发表评论