2

I have the following classes in a header file designed to create runtime polymorphism for a set of instructions that describe system states in an embedded environment:

class foo
{
public:
  virtual void bar(void) = 0;
  virtual ~foo() {}
};

class derived1 : public foo
{
private:
  int data1;
public:
  void bar(void)
  {
    //implementation 1
  };
  derived1(int d) : data1(d) {}
  ~derived1() {}
};

class derived2 : public foo
{
private:
  int data2;
public:
  void bar(void)
  {
    //implementation 2
  }
  derived2(int d) : data2(d) {}
  ~derived2() {}
};

What is the best way to initialize a vector of type const vector<foo*>? I am currently doing the following:

const std::vector<foo*> v =
{   
  new derived1(a),
  new derived1(b),
  new derived2(c),
  new derived2(d)
};

Given the const qualifier, is this memory still dynamically allocated? It is stored in an anonymous namespace for use by several state classes. Because many state classes share the same elements I wanted to define the vector for all of them to chose from to save code space. Is a vector best suited for this behavior?

Ps, I do not need to worry about calling delete on any of the pointers since the application requires this information for all runtime.

user4581301
  • 33,082
  • 7
  • 33
  • 54
nathanPPS
  • 23
  • 1
  • 4
  • 1
    `const std::vector> v = { new derived1(a), new derived1(b), ...... }` seems like a good option – M.M Jan 28 '20 at 01:07
  • 1
    Not quite sure what exactly you are aiming for. Do you NOT want these dynamically allocated? In case this matters to you, as used `const` means the pointers cannot be changed, but nothing is going to protect the pointed-at objects from being changed. – user4581301 Jan 28 '20 at 01:30
  • For embedded systems design, you should simply ban the following items: dynamic allocation, `std::vector`, STL, C++11, C++. – Lundin Jan 28 '20 at 09:38
  • For this implementation, static allocation may be better since the data needs to be accessible during the entire runtime, though using a vector gives me more flexibility. – nathanPPS Jan 28 '20 at 16:54

1 Answers1

2

Given the const qualifier, is this memory still dynamically allocated?

Yes. std::vector internally allocates and const or no const won't change that.

What is the best way to initialize a vector of type const vector<foo*>?

Best is really subjective here, but there are generally two good ways I like to use:

  • initialise with braces to use std::initializer_list;
  • use IIFE (Immediately Invoked Function Expression);

The first one is obvious - you are already using it. The second one is tricker if you've never used that:

const std::vector<int> vec = [someFlag]{
    std::vector<int> non_const;

    non_const.push_back(3);
    if (someFlag) {
        non_const.push_back(-1);
    }
    non_const.push_back(7);

    return non_const;
}(); // <= notice the call - ()

Notice that you end up with a const std::vector which is conditionally initialised (notice the if inside the lambda). The trick is to use a lambda and a local, non-const vector to push some values into it and then return it. Due to mandatory copy elision, there should be exactly one contruction of std::vector. The compiler is free to optimise (and likely will) any vector copies, so most of the time there will be just one std::vector creation.

Fureeish
  • 12,533
  • 4
  • 32
  • 62
  • 1
    https://stackoverflow.com/questions/38043319/how-does-guaranteed-copy-elision-work (see end of top answer) – M.M Jan 28 '20 at 01:30
  • Thanks for the IIFE initializer! I haven't seen this one before, but I like it because of the added functionality. Probably not necessary for the above implementation, but may be useful elsewhere. – nathanPPS Jan 28 '20 at 17:01