Are Parent Class Constructors Called Before Initializing Variables

Are parent class constructors called before initializing variables?

Yes, the base class is initialized before the members of the derived class and before the constructor body executes.

12.6.2 Initializing bases and members [class.base.init]

In a non-delegating constructor, initialization proceeds in the
following order:

— First, and only for the constructor of the most
derived class (1.8), virtual base classes are initialized in the order
they appear on a depth-first left-to-right traversal of the directed
acyclic graph of base classes, where “left-to-right” is the order of
appearance of the base classes in the derived class
base-specifier-list.

— Then, direct base classes are initialized in
declaration order as they appear in the base-specifier-list
(regardless of the order of the mem-initializers).

— Then, non-static
data members are initialized in the order they were declared in the
class definition (again regardless of the order of the
mem-initializers).

— Finally, the compound-statement of the
constructor body is executed.

What are the rules for calling the base class constructor?

Base class constructors are automatically called for you if they have no argument. If you want to call a superclass constructor with an argument, you must use the subclass's constructor initialization list. Unlike Java, C++ supports multiple inheritance (for better or worse), so the base class must be referred to by name, rather than "super()".

class SuperClass
{
public:

SuperClass(int foo)
{
// do something with foo
}
};

class SubClass : public SuperClass
{
public:

SubClass(int foo, int bar)
: SuperClass(foo) // Call the superclass constructor in the subclass' initialization list.
{
// do something with bar
}
};

More info on the constructor's initialization list here and here.

Initialize Derived class member variable before calling Base class constructor. Is this UB?

I would like to initialize a member variable of a Derived class, and after that pass it to the Base class constructor.

In C++, the order of construction is of the base part(s) before the derived parts. This is because it is far more common for the derived parts to (potentially) be constructed in terms of the base parts. In order to make this well-defined, the base-then-derived order is specified. Using derived in the base is undefined, therefore.

If you want your base to use derived members, there's a way to ensure the order is OK. Make the "members" base classes too. Note that boost::base_from_member is built exactly for making this more convenient.

Say you have some

class member_type{};

And you'd like to have derived have a member_type member, and derive from base. Then you could use:

class derived : 
private boost::base_from_member<member_type>,
public base {
using my_member_type = private boost::base_from_member<member_type>;

public:
derived();
};

Note that now derived subclasses both my_member_type and base (in that order). Hence, the latter can use the former in its construction.

derived::derived() : 
my_member_type{3},
base{my_member_type::member} {
}

Initialize member before base constructor. Possible?

i is a data member of class B, so in order to be created, an object of class B has to be created first. So the answer, is no.

How do I call the base class constructor?

You do this in the initializer-list of the constructor of the subclass.

class Foo : public BaseClass {
public:
Foo() : BaseClass("asdf") {}
};

Base-class constructors that take arguments have to be called there before any members are initialized.



Related Topics



Leave a reply



Submit