As you might know, you cannot initialize a base member in a derived constructors initializer list:
struct Base { int base_mem; }; struct Derived : public Base { Derived(int i) : base_mem(i) {} //Error! }; int main() { Derived(42); }
This is not allowed. But why? There are two key points to get here:
1: What is the point of an initializer list in the first place?
If you don’t use an initializer list, but initialize all your objects in the constructor body, they will first be created once, even before the constructor body, and then you will re-assign them. This might be a performance-problem, but could also be a bigger problem if the constructors of those types have side-effects like hitting a database, acquiring some resource etc.
2: When are the different parts of an object constructed?
When constructing a Derived
object, the first thing that happens is that Base
s default constructor is invoked. In this example, I didn’t declare one, so the compiler will generate one for me. When this constructor is done, including both its initializer-list and its body, it is Derived()
s turn.
This means that when C++ gets around to Derived()
s initializer, the Base
part of the object has already been created, all Base
members are initialized, and we have lost the advantage of using initializer lists.
So how do we solve this? Make sure the Derived
constructor explicitly specifies which Base
constructor to use, and have this one initialize the variable. Example:
struct Base { Base(int i) : base_mem(i) {} int base_mem; }; struct Derived : public Base { Derived(int i) : Base(i) {} };