FAQ
Q1. what is the output of the following code?
1#include <iostream>2 using namespacestd;3 4 classA5 {6 Public: 7A () {cout <<"A"<<Endl;}8~a () {cout <<"~a"<<Endl;}9 }; Ten classD | PublicA One { A Public: -B (a &a): _a (a) {cout <<"B"<<Endl;} -~b () {cout <<"~b"<<Endl;} the Private: - A _a; - }; - + intMainintargcChar*argv[]) - { + A; A b b (a); at return 0; -}
Q2. The result of the output after test execution is ()
1 voidTest ()2 {3 classB4 {5 Public:6B () {cout <<"b\t"; }7~b () {cout <<"~b\t"; }8 }; 9 structCTen { OneCvoid) {cout <<"c\t"; } A~c (void) {cout <<"~c\t"; } - }; - structd:b the { - Public: -D () {cout <<"d\t"; } -~d () {cout <<"~d\t"; } + Private: - c C; + }; A d D; at}
A. B C D ~d ~c ~b
B. D C B ~b ~c ~d
C. C D B ~b ~d ~b
D. C ~c D ~d B ~b
the call order of constructors and destructors
1. Destructors
One purpose of the constructor is to get the resource automatically. For example, a constructor can allocate a buffer or open a file, and after assigning a resource in the constructor, a corresponding operation is required to automatically reclaim or dispose of the resource. A destructor is a special function that can be used to retrieve the required resources as a complement to a class function.
Destructors are automatically applied when objects that are out of scope or are dynamically allocated are deleted. Destructors can be used to dispose of resources obtained during the construction of an object or in the life cycle of an object.
The compiler automatically executes destructors for non-static data members of the class, regardless of whether the class defines its own destructor.
Although constructors are not defined as virtual functions, destructors can be defined as virtual functions, in general, if a virtual function is defined in a class, the destructor should also be defined as a virtual function, especially if there is a request for dynamic memory within the class, which needs to be cleaned up and released.
2. Sequence of calls for constructors and destructors
(1) Single inheritance
When derived, constructors and destructors cannot be inherited, and in order to initialize a base class member, the constructor and destructor must be redefined on the derived class, and the constructor of the base class is called in the initializer list of the constructor.
Because derived class objects contain base class data members through inheritance, when you create a derived class, the system first calls the constructor of the base class by the constructor of the derived class, completes the initialization of the base class member, and then initializes the new member in the derived class.
The general format of a derived class constructor is:
1 derived class name (General Staff tables): base class Constructors (parameter table) 2 {3 // 4
The constructor of the base class must be placed in the initialization list of the derived class to call the base class constructor to complete initialization of the base class data member (if none, call the default constructor of the base class), the function implemented by the derived class constructor, or the order of invocation is:
1). The completion of the whole block memory of the object is completed by the system when the constructor is called;
2). Call the constructor of the base class to complete the initialization of the base class member;
3). If the derived class contains an object member, a const member, or a reference member, its initialization must be done in the initialization table;
4). Derived class constructor body execution.
When the object is deleted, the destructor of the derived class is executed. Destructors cannot be inherited, so the base class destructor is called automatically when the class destructor is executed. The order of execution is to execute the destructor of the derived class first, and then the destructor of the base class, which is the reverse of the order in which the constructor was executed.
(2) Multiple inheritance
When multiple inheritance occurs, the constructor initialization list for the derived class requires calling the constructors of each base class. The sequence of destructors is still executed in reverse order of the constructor's operation.
Note: The constructor initialization list now controls only the values used to initialize the base class, and cannot control the construction order of the base class. The base class constructor is called in the order in which the base class constructors appear in the class-derived list.
For example, the following inheritance relationship:
1#include <iostream>2 using namespacestd;3 4 classZooanimal5 {6 Public:7Zooanimal () {cout <<"Zooanimal"<<Endl;}8~zooanimal () {cout <<"~zooanimal"<<Endl;}9 }; Ten classBear: PublicZooanimal One { A Public: -Bear () {cout <<" Bear"<<Endl;} -~bear () {cout <<"~bear"<<Endl;} the }; - classendangered - { - Public: +Endangered () {cout <<"endangered"<<Endl;} -~endangered () {cout <<"~endangered"<<Endl;} + }; A classPanda: PublicBear, Publicendangered at { - Public: -Panda (): Endangered (), bear () {cout <<"Panda"<<Endl;} -~panda () {cout <<"~panda"<<Endl;} - }; - in intMainintargcChar*argv[]) - { to Panda p; + return 0; -}
Analysis:
(3) Virtual inheritance
The constructor of the virtual base class is called first, and if there are multiple virtual base classes, the order in which the virtual base class constructors are called is the order in which this virtual base class appears in the current class-derived table instead of the sequence in which they are in the Member initialization table.
After all the constructor calls for the virtual base class are complete, the other constructors are called according to the Rules of (2).
Sequence of calls to the "C + +" constructors and destructors