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?
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.