1

I have following code:

class Base
{
public:
    Base(int test) { std::cout << "Base constructor, test: " << test << std::endl; }
};

class Derived : public Base
{
private:
    int variable;

public:
    Derived() :
        variable(50),
        Base(variable)
    {}
};

Derived derived;

And I would expect that output would be: "Base constructor, test: 50", but that isn't the case, because Base constructor gets called before variable is initialized, there is no error nor warning, it just compiles.

Is there any way i can make Base constructor get called after ? Or is this generally bad design ?

I'm tryting to get rid of all the init methods and their calls by putting them into constructor insted, this behavior stop me from doing that.

Kazz
  • 1,030
  • 8
  • 16
  • 1
    Activate warning, `: variable(50), Base(variable)` is a wrong order. – Jarod42 Apr 15 '21 at 14:58
  • 2
    [base-from-member-idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Base-from-Member). – Jarod42 Apr 15 '21 at 15:08
  • Shame this was closed: I was writing an answer for you suggesting to use `Derived() : Base(variable = 50) {} ` for your derived c'tor. – Adrian Mole Apr 15 '21 at 15:11
  • Shame this was closed: The question closing invalidated my answer - look into **delegating constructors** if you ever need a value to be produced **before** any constructors are called. – Drew Dormann Apr 15 '21 at 15:11
  • @AdrianMole - given that there were two answers in the queue, I am reopening. Please add your answer! – Drew Dormann Apr 15 '21 at 15:12

1 Answers1

5

Is there any way i can make Base constructor get called after?

No. An object's constructor must construct its base classes before any named member variables.

I'm trying to get rid of all the init methods and their calls by putting them into constructor instead

That is a worthwhile effort!

I'll assume your real code variable is something more complex than an int. Because if it's an int, you could simply call Base(50).

You can use delagating constructors to prepare a variable before any constructor begins initialization.

class Derived : public Base
{
public:
    // Generate an important value FIRST, and then delegate
    // construction to a new constructor.
    Derived() : Derived( GenerateSomethingComplex() ) {}

private:

    // Here, we can honor constructing Base before Derived
    // while "some value" has been procured in advance.
    Derived( SomethingComplex&& var) :
        Base( var ),
        variable( std::move(var) )
    {}

    SomethingComplex variable;

};
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180