When you write a constructor — any constructor — for a derived class, you can (and often should) explicitly initialize the base class subobjects in this list of constructor initializers. If you do not, the compiler will indirectly call the default constructors for these base class subobjects, assuming they are available. This rule applies to absolutely all custom constructors.
This is exactly what happened in your case. You forgot to initialize the base constructor A
to B::B(const B&)
, so the default constructor was used for this base. The fact that B::B(const B&)
is a copy constructor does not matter in this case. It works the same way, sequentially, for all types of user-defined constructors.
Now, if you do not provide a custom copy constructor, the compiler will try to provide implicitly. An implicit copy constructor will attempt to invoke copy constructors for all base classes. The language specification simply says that such a constructor, created by the compiler, behaves in such a way that is the answer to your question “why”.
source share