Consider a code
struct X {
X (int n) {...}
};
struct Base {
Base(X & x) {...}
};
struct Derived : public Base {
Derived() : Base(x), x(2) {}
X x;
};
Code works and i see no issue there but i'm concerned about the look of : Base(x), x(2)
statement. First pass the instance to Base
and after you initialize the actual object. Is this the the only way to express the intention?
The trick is to derived from one more base class who's function is to own the X
.
Note that base class declaration order matters:
struct X {
X (int n) {}
};
struct Base {
Base(X & x) {}
};
struct OwnsAnX {
OwnsAnX(int n) : x_(n) {}
X& get_x() { return x_; }
private:
X x_;
};
struct Derived
: OwnsAnX // note: order is important
, Base
{
Derived()
: OwnsAnX(2)
, Base(get_x())
{}
// x is accessed through the inherited get_x()
};
but it's error prone if you don't keep the correct order of the classes you're inheriting from
This is a valid concern of the OP. The solution is to enable the compiler warning -Wreorder
.
Reversing the order of the base classes then yields:
<source>: In constructor 'Derived::Derived()':
<source>:24:23: warning: base 'OwnsAnX' will be initialized after [-Wreorder]
, Base(get_x())
^
<source>:24:23: warning: base 'Base' [-Wreorder]
<source>:22:9: warning: when initialized here [-Wreorder]
Derived()
^~~~~~~
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With