The function and principle analysis of base class virtual destructor in C + +

Source: Internet
Author: User

The theoretical premise of virtual destructor is

After executing the destructor of the subclass, the fictitious function of the parent class is bound to be executed.

Then when you use Delete to release a subclass object that is instantiated by a parent pointer, if you do not define a virtual destructor, only the destructor of the parent class will be called, and the fictional function of the subclass will not be called, resulting in a memory leak.

Therefore: When inheriting, a good habit to develop is the base class destructor, plus virtual.

Knowledge background

To understand this problem, first understand the dynamic binding in C + +.

For an explanation of dynamic bindings, see: Dynamic types and dynamic bindings, virtual functions, polymorphic implementations in C + +

Business

Directly speaking, the base class in C + + uses virtual virtual destructor to prevent memory leaks. Specifically, if memory space is requested in the derived class, and the memory space is disposed of in its destructor. Suppose a non-virtual destructor is used in a base class, and when you delete a derived class object that the base class pointer points to, it does not trigger dynamic binding, and therefore only the destructor of the base class is called, not the destructor of the derived class. In this case, the requested space in the derived class is not released, resulting in a memory leak. Therefore, in order to prevent the occurrence of this situation, the destructor of the base class in C + + should use virtual virtual destructor.

Sample Code Explained

The existing base base class whose destructor is a non-virtual destructor. Derived1 and Derived2 are derived classes of base, both of which have string* point to the address space where their name is stored, and the name object is an object created on the heap through new, so when you refactor, you need to explicitly call Delete to remove the pointer to return memory. Failure to do so will result in a memory leak.

Class Base {public:~base () {  cout << "~base ()" << Endl;}};

  

Class Derived1:public Base {public:  Derived1 (): Name_ (New String ("NULL")) {}  Derived1 (const string& N): Name_ (new string (n)) {}  ~derived1 () {    delete name_;    cout << "~derived1 (): Name_ has been deleted." << Endl;  } Private:  string* name_;}; Class Derived2:public Base {public:  Derived2 (): Name_ (New String ("NULL")) {}  Derived2 (const string& N): Name_ (new string (n)) {}  ~derived2 () {    delete name_;    cout << "~derived2 (): Name_ has been deleted." << Endl;  } Private:  string* name_;};

Let's take a look at the following to test the condition of its destruction:

D1 is a pointer to the Derived1 class that points to an object created on the heap Derived1, and D2 to an object created on the stack. Where D1 refers to an object that requires us to explicitly invoke its destructor with delete, and the D2 object will automatically call its destructor at the end of its life cycle. Look at the results of the operation:

As we said, the destructor of the base class is not a virtual destructor, and now the result shows that the destructor of the derived class is called and the memory resource of the application is freed normally. The two are not contradictory, because both are static bindings, both D1 and D2, and their static types happen to be derived classes, so the destructor of the derived class is called even if the destructor of the base class is a non-virtual destructor at the time of the destructor.

Let's take a look at what happens when a dynamic binding occurs, that is, when a base class pointer is used to point to a derived class, when a delete explicitly deletes the object that the pointer is referring to, if the destructor of the base class does not have virtual?

int main () {  base* base[2] = {    new Derived1 (),    new Derived2 ("Bob")        };  for (int i = 0; I! = 2; ++i) {    delete base[i];      }  return 0;}

  

From the above results we see that although a destructor is defined in a derived class to release its requested resource, it has not been called. The reason is that the base-class pointer points to the derived class object, and the destructor in the base class is non-virtual, as previously mentioned, virtual functions are the basis of dynamic binding . The destructor is now not virtual, so dynamic binding does not occur, but static binding, the static type of the pointer is a base-class pointer, so only the destructor of the base class is called at Delete, but not the destructor of the derived class. In this way, the resources requested in the derived class will not be freed, resulting in a memory leak, which is quite dangerous: if there are a large number of derived class objects in the system that are created and destroyed, there will be a constant leak of memory, over time, the system will crash due to the lack of memory.

That is, when the destructor of a base class is a non-virtual destructor, it does not necessarily cause a memory leak; when there is memory in the destructor of the derived class object that needs to be retracted, and the base class pointer is used in the programming process to point to the derived class object, such as to implement polymorphism and destroy the object through a base-class pointer, Because the destructor of the base class is not a virtual destructor and does not trigger dynamic binding, the destructor of the derived class is not invoked to cause a memory leak.

Therefore, in order to prevent the occurrence of memory leaks in this case, it is best to write the destructor of the base class into virtual virtual destructor.

The following changes the destructor of the base class to the virtual destructor:

Class Base {public:virtual ~base () {  cout << "~base ()" << Endl;}};

 

 

This will enable dynamic binding, and the destructor of the derived class will be called, thus avoiding a memory leak.

This article was reproduced in: https://www.cnblogs.com/liushui-sky/p/5824919.html

The function and principle analysis of base class virtual destructor in C + +

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.