Seriously
Seriously

Reputation: 990

Initialize member reference with default value

I have a class with a std::vector const& member which shall be set through the constructor. However, it should also be possible to omit this parameter in the constructor and let the member be initialized by a default value.

Example Code:

class MyClass {
public:
  MyClass(int a, const std::vector<int> &v = {42,42,42}) : vec(v){}

  const std::vector<int> &vec;
};

int main(void) {

  std::vector<int> a{1,2,3};

  MyClass c1(1,a);              // c1.vec = 1,2,3
  MyClass c2(1);                // c2.vec = randomStuff
                                // should actually be 42,42,42
}

If I change the initialization to:

MyClass(int a, const std::vector<int> &v = *(new std::vector<int>{42,42,42})) : vec(v){}

Everything works fine since the temporary vector is not deleted when going out of scope. However, this doesn't feel right and look memory leaky. Is there a saner way to achieve the expected behavior?

Upvotes: 1

Views: 128

Answers (1)

You can define the default argument as a static data member of your class:

class MyClass {
 public:
  MyClass(int a, const std::vector<int> &v = defaultVec) : vec(v){}

  const std::vector<int> &vec;

 private:
  static const std::vector<int> defaultVec;
};

const std::vector<int> MyClass:defaultVec{42, 42, 42};

To keep the class header-only, you can also use a static variable in a static member function instead:

class MyClass {
 public:
  MyClass(int a, const std::vector<int> &v = defaultVec()) : vec(v){}

  const std::vector<int> &vec;

 private:
  static const std::vector<int>& defaultVec()
  {
   static const std::vector<int> v {42, 42, 42};
   return v;
  }
};

Note that either way, the vector used as the default argument has to have static storage duration, so that it remains valid after the constructor finishes running.

Upvotes: 4

Related Questions