I must add to the previous answers because everyone seems to be ignoring it
When you have a derived class instance being created, it is true that the code inside the constructor of the base will be called before the code inside the constructor of the derived, but keep in mind that the derived is still technically "created" before the base.
And when you have the derived class destructor being called, it is true that the code inside the derived destructor is called before the code inside the base destructor, but also keep in mind that the base is destroyed before the derived.
When I am saying created/destroyed I am actually referring to allocated/deallocated.
If you look at the memory layout of these instances, you will see that the derived instance composes the base instance. For example:
Memory of derived: 0x00001110 to 0x00001120
Memory of base : 0x00001114 to 0x00001118
Therefore, the derived class must be allocated BEFORE the base in the construction. And the derived class must be deallocated AFTER the base in the destruction.
If you have the following code:
class Base
{
public:
Base[]
{
std::cout
class Derived : T {
using T::T; // declare the constructors from T
// ...
};
A deriving class can't inherit from multiple base classes if those base classes have constructors that have an identical signature.
Constructors and composite classes
Classes that contain class-type members are known as composite classes. When a class-type member of a composite class is created, the constructor is called before the class's own
constructor. When a contained class lacks a default constructor, you must use an initialization list in the constructor of the composite class. In the earlier StorageBox
example, if you change the type of the m_label
member variable to a new Label
class, you must call both the base class constructor and initialize the m_label
variable in the StorageBox
constructor:
class Label {
public:
Label[const string& name, const string& address] { m_name = name; m_address = address; }
string m_name;
string m_address;
};
class StorageBox : public Box {
public:
StorageBox[int width, int length, int height, Label label]
: Box[width, length, height], m_label[label]{}
private:
Label m_label;
};
int main[]{
// passing a named Label
Label label1{ "some_name", "some_address" };
StorageBox sb1[1, 2, 3, label1];
// passing a temporary label
StorageBox sb2[3, 4, 5, Label{ "another name", "another address" }];
// passing a temporary label as an initializer list
StorageBox sb3[1, 2, 3, {"myname", "myaddress"}];
}
In this section
- Copy constructors and copy assignment operators
- Move constructors and move assignment operators
- Delegating constructors
See also
Classes and structs
Feedback
Submit and view feedback for