[C++ Notes] C++ structure and destructor execution order

Not long ago, a friend met with a back-end development post recruited by Tencent and talked with him. He said that Tencent's side is still more basic. There are more questions about C++, operating systems, networks, and algorithms, even if it is social recruitment. . Among them, there is a question about the construction and destruction order of C++ when it comes to virtual inheritance. I don’t pay much attention to it at ordinary times, so it really embarrassed many interviewers. My friend is one of them, so it is necessary to summarize it. .

In C++, when a class object is created, the compiler will automatically call something called a constructor. We know that C++ classes and classes are related in many cases, such as inheritance, composition, etc., read This topic is described in the article Understanding UML Class Diagrams (please poke me). This article mainly summarizes the sequence of construction and destruction in various situations through examples.

inherit

Scenario: Class B inherits two parent classes A and C. The constructor and destructor of each class are very simple, just print the corresponding function name to observe the execution order of the construction and destructor.

#include <iostream>

using namespace std;

class A
{    
    public:        
        A(){cout << "A()" << endl;}       
        ~A(){cout << "~A()" << endl;}
};

class C
{    
    public:        
        C(){cout << "C()" << endl;}        
        ~C(){cout << "~C()" << endl;}
};

class B: public A, public C
{    
    public:        
        B(){cout << "B()" << endl;}        
        ~B(){cout << "~B()" << endl;}
};

int main(int argc, char const *argv[])
{    
    B b;    
    return 0;
}
bogon:dataStructure lizhong$ ./t
A()
C()
B()
~B()
~C()
~A()

It can be seen from the running results: when creating a subclass object, first execute the constructor of the parent class, and then execute its own constructor. If the subclass inherits multiple parent classes, the parent class will be called from left to right in the order of inheritance. Constructor (in this example, first construct A, then construct C), the order of destruction is opposite to the order of construction.

We also know that there is another kind of inheritance called virtual inheritance. Let's take a look at the order of construction and destruction in this case.

#include <iostream>

using namespace std;

class A
{    
    public:        
        A(){cout << "A()" << endl;}       
        ~A(){cout << "~A()" << endl;}
};

class C
{    
    public:        
        C(){cout << "C()" << endl;}        
        ~C(){cout << "~C()" << endl;}
};

class B: public A, public C
{    
    public:        
        B(){cout << "B()" << endl;}        
        ~B(){cout << "~B()" << endl;}
};

int main(int argc, char const *argv[])
{    
    B b;    
    return 0;
}
bogon:dataStructure lizhong$ ./t
C()
A()
B()
~B()
~A()
~C()

It can be seen that the order of virtual inheritance and general inheritance construction and destruction is still a bit different. The construction order of the parent class has changed. The C constructor of virtual inheritance is executed first, and then A. Finally, its own constructor is called, and the order of destruction is opposite to the order of construction.

Members include other class object members

Scenario: Class B contains members of class A objects and class C objects, and in class B, the order of declaration of its members is to declare c first, then a. Take a look at the execution order of the constructor and destructor when creating a class B object.

#include <iostream>

using namespace std;

class A
{    
    public:        
        A(){cout << "A()" << endl;}       
        ~A(){cout << "~A()" << endl;}
};

class C
{    
    public:        
        C(){cout << "C()" << endl;}        
        ~C(){cout << "~C()" << endl;}
};

class B
{    
    public:        
        B():a(A()), c(C()) {cout << "B()" << endl;}        
        ~B(){cout << "~B()" << endl;}
        C c;  
        A a;
};

int main(int argc, char const *argv[])
{    
    B b;    
    return 0;
}
bogon:dataStructure lizhong$ ./t
C()
A()
B()
~B()
~A()
~C()

The results of the operation can be seen: when creating a class B object b, first execute the constructor of the class to which its member object belongs, and then execute its own constructor. If there are multiple class object members, call the corresponding class structure in the order of declaration Function (in this example, first construct the C-type object c, then construct the A-type object a), the order of destruction is opposite to the order of construction.

Both inheritance and class object members

Scenario: Class B inherits two parent classes A and C, and class B has an object member of class X. Observe the execution order of construction and destructor functions.

#include <iostream>
using namespace std;

class A
{
    public:
        A(){cout << "A()" << endl;}
        ~A(){cout << "~A()" << endl;}
};

class C
{
    public:
        C(){cout << "C()" << endl;}
        ~C(){cout << "~C()" << endl;}
};

class X
{
    public:
        X(){cout << "X()" << endl;}
        ~X(){cout << "~X()" << endl;}
};

class B: public A, public  C
{
    public:
        B(){cout << "B()" << endl;}
        ~B(){cout << "~B()" << endl;}
        X x;
};

int main(int argc, char const *argv[])
{
    B b;
    return 0;
}
bogon:dataStructure lizhong$ ./t
A()
C()
X()
B()
~B()
~X()
~C()
~A()

The results of the operation can be seen: when the class is constructed, it will first call the constructor of the parent class from left to right, then call the member constructor of the class object, and finally call its own constructor. The order of destruction is opposite to the order of construction.

Recommended reading:

Carefully organized | Historical dry goods article catalog
[welfare] I collected online boutique course video sharing (part 1)
[data structure and algorithm] easy to understand binary tree traversal
[data structure and algorithm] easy to understand binary search tree

Focus on server background technology stack knowledge summary sharing

Welcome to pay attention to communication and common progress

[C++ Notes] C++ structure and destructor execution order

Coding

The code farmer has the right way to provide you with easy-to-understand technical articles to make technology easier!

Guess you like

Origin blog.51cto.com/15006953/2552126