When Constructive and Destructive Forces Converge in Object-Oriented Programming: A Case Study in Class Inheritance
When creating objects within inheritance hierarchies, a fundamental question arises regarding the order in which constructors and destructors are invoked. This inquiry centers around the behavior of both base and derived classes, as well as the impact of member fields within those classes. To unravel this enigma, let us delve into an illustrative example.
Consider the following C code snippet:
struct A { A() { std::cout << "A() C-tor" << std::endl; } ~A() { std::cout << "~A() D-tor" << std::endl; } }; struct B : public A { B() { std::cout << "B() C-tor" << std::endl; } ~B() { std::cout << "~B() D-tor" << std::endl; } A a; };
Here, we have two classes, A and B, where B inherits from A. Within class B, a member field a of type A is also defined. Upon creating an instance of class B, the order of constructor calls and destructor calls becomes a matter of fascination.
The Mechanics of Construction
As the code executes, the construction of an object begins with its base class. In this case, the A class is the base class for B, so the A() constructor will be invoked first. Following this, the member fields of the derived class are constructed. Since class B has a member field a of type A, the A() constructor will be invoked again during this stage. Finally, the constructor for the derived class, B(), is called, signifying the completion of object construction.
Descending into Destruction
When an object's lifecycle comes to an end, the order of destructor calls follows an inverse pattern. The member fields are destroyed first, proceeding in reverse order of their declaration. In our example, class B's member field a (an instance of class A) will have its destructor, ~A(), invoked. This is followed by the destruction of the derived class itself, triggering the invocation of ~B(). Lastly, the destructor of the base class, ~A(), is called.
Irrespective of Initialization Lists
It is noteworthy that the order of constructor and destructor calls remains unaffected by the presence or absence of an initializer list. In the code snippet provided, there is no initializer list, but the order of invocation described above still holds true. This consistent pattern ensures a predictable flow of construction and destruction across various inheritance scenarios.
The above is the detailed content of In C Inheritance, What's the Order of Constructor and Destructor Calls in Base and Derived Classes?. For more information, please follow other related articles on the PHP Chinese website!