Question

I have a class MyClass in which I need to create a std::array of std::vector in the default constructor. However, this class has a data member which is a reference (of type Something) which also needs to be initialized in the constructor and I cannot do this in a default constructor.

How should I solve this?

class MyClass{
public:
    MyClass(); //Cannot instantiate s??
    MyClass(Something& s);
    Something& s;
}

MyClass array[10];   // MyClass needs a default constructor but a default 
                     // constructor won't be able to initialize s
Was it helpful?

Solution

A class with a reference member needs to set the reference in its constructors. In most cases this means, that the class cannot have a default constructor. The best way to solve the problem is use a pointer instead of a reference:

class MyClass{
public:
    MyClass() : s_(0) {}
    MyClass(Something* s) : s_(s) {}
    Something* s_;
}

OTHER TIPS

As I commented above, by the description alone, I would say that it's a classical case where s should be a Something* rather than a Something&...

OTOH, this work perfectly, so you don't need a default constructor if you just initialize each element of your array:

struct Something { };

struct MyClass {
  MyClass(Something& ss) : s{ss} {}
  Something& s;
};

int main() {
  Something a, b, c, d;
  Something v[10] = { a, b, c, d, a, b, c, d, a, b };
  return 0;
}

Your can also do this:

class MyClass{
public:
    MyClass() : s_(0) {}
    MyClass(Something& s) : s_(&s) {}
    Something* s_;
}

You can use std::optional<std::reference_wrapper<Something>> instead of Something&, this way you simulate Something* behavior but using modern C++ concepts. note that you should check if member variable defined this way has value by calling has_value function and get the actual reference value by s_.value().get() you also could use std::optional<std::reference_wrapper<const Something>> if you need a const reference to Something

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top