Why should the destructor of the base class be written as a virtual function?

Why should the destructor of the base class be written as a virtual function?

 Answer: When implementing polymorphism, when using the base class to operate the derived class, prevent the situation where only the base class is destructed without destructing the derived class when destructing.

 

The code description is as follows

The first piece of code:

 1 #include<iostream>
 2 using namespace std;  
 3  4class ClxBase  
 5 {public:  
 6 ClxBase() {}  
 7    ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl}  
 8 9void DoSomething() { cout << "Do something in class ClxBase!" << endl; }  
10};  
1112class ClxDerived : public ClxBase  
13 {  
       
        
 public:   
14    ClxDerived() {}  
15    ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl}  
16 17void DoSomething() { cout << "Do something in class ClxDerived!" << endl; }  
18};   
1920int main()  
21{  
22    ClxDerived *p =  new ClxDerived;   
23    p->DoSomething();   
24delete p;   
2526  
        
         
    return 0;   
27 }  

operation result:

Do something in class ClxDerived!   

Output from the destructor of class ClxDerived!

Output from the destructor of class ClxBase!  

 

The destructor of the base class in this code is not a virtual function. In the main function, the pointer of the inherited class is used to operate the members of the inherited class. The process of releasing the pointer P is: first release the resources of the inherited class, and then release the resources of the base class. 

 

Second piece of code:

 1 #include<iostream>
 2 using namespace std;  
 3  4class ClxBase  
 5 {public:   
 6ClxBase() {}  
 7    ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl}  
 8 9void DoSomething() { cout << "Do something in class ClxBase!" << endl}  
10};  
1112class ClxDerived : public ClxBase  
13 {  
        
        
 public:   
14    ClxDerived() {}  
15    ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl }  
16 17void DoSomething() { cout << "Do something in class ClxDerived!" << endl}  
18};  
1920int main()  
21{   
22    ClxBase *p =  new ClxDerived;   
23    p->DoSomething();   
24delete p;   
2526return  
        
         
     0;   
27 }   

Output result:

Do something in class ClxBase! 

Output from the destructor of class ClxBase!

 

 The destructor of the base class in this code is also not a virtual function. The difference is that the pointer of the base class is used in the main function to operate the members of the inherited class. The process of releasing the pointer P is: only the resources of the base class are released, and The destructor of the inherited class is not called. Calling the dosomething() function executes the function defined by the base class.

 

 Under normal circumstances, such deletion can only delete the base class object, but cannot delete the subclass object, forming a deleted half image, resulting in a memory leak.

 

 In public inheritance, the operation of the base class on the derived class and its objects can only affect those members inherited from the base class. If you want to use the base class to operate on non-inherited members, you need to use this function of the base class. Defined as a virtual function.

A destructor should naturally do the same: if it wants to destruct redefines or new members and objects in a subclass, it should of course also be declared virtual. 

 

The third piece of code:

 1 #include<iostream> 2usingnamespace std;  
 3class ClxBase  
 4 {public:   
 5ClxBase() {}   
 6virtual ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl}  
 7 8virtualvoid DoSomething() { cout << "Do something in class ClxBase!" << endl}  
 9};  
101112class ClxDerived : public  
              
         
   
  ClxBase  
13 {public:   
14    ClxDerived() {}   
15    ~ClxDerived() { cot << "Output from the destructor of class ClxDerived!" << endl}  
16 17void DoSomething() { cout << "Do something in class ClxDerived!" << endl}  
18};  
1920int   main()  
21{  
22    ClxBase *p = new ClxDerived;  
23    p->DoSomething();   
24delete p;  
  
        
      25 26return0;  
27 }    
     

operation result:

Do something in class ClxDerived!

Output from the destructor of class ClxDerived!

Output from the destructor of class ClxBase!

 

In this code, the destructor of the base class is defined as a virtual function. In the main function, the pointer of the base class is used to operate the members of the inherited class. The process of releasing the pointer P is: just release the resources of the inherited class, and then call the base class. The destructor of the class. Calling the dosomething() function executes the function defined by the inherited class.  

 

If you do not need the base class to operate on derived classes and objects, you cannot define virtual functions, because this will increase memory overhead. When a virtual function is defined in a class, the compiler will add a virtual function table to the class to store it. Virtual function pointer, which will increase the storage space of the class. Therefore, only when a class is used as a base class, write the destructor as a virtual function.

 

 

Note: This content is for reference, the purpose is to learn from each other and make progress together with everyone

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325846996&siteId=291194637