4

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?

5
  • See this: stackoverflow.com/q/7539282/10077 Commented Apr 4, 2017 at 18:07
  • I would not use X as the name of the struct. This will definitely cause you and others headaches down the road... Commented Apr 4, 2017 at 18:07
  • 2
    AFAIK, base class is always initialized before members of derived class, so this is not safe if constructor of the base class trying to do anything with the parameter, beside storing reference to it. Commented Apr 4, 2017 at 18:09
  • The code as shown is valid, unless {...} in Base tries to access the value of x, which isn't there yet. Commented Apr 4, 2017 at 18:15
  • @NO_NAME Yes, the only thing in Base() is storing the reference. Commented Apr 4, 2017 at 18:42

1 Answer 1

5

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() ^~~~~~~ 
Sign up to request clarification or add additional context in comments.

2 Comments

Definitely an option but it's error prone if you don't keep the correct order of the classes you're inheriting from. I'm still considering that this problem is best solved by register(X * x) method in Base class.
@PeterSilon ordering is always a factor in inheritance and initialisation. You must do as you see fit.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.