The destructor of C++ base class is a virtual function

  • 2020-05-05 11:32:56
  • OfStack

1. Reason:

In the implementation of polymorphism, when the base class pointer is used to manipulate the derived class, the destructor is prevented from destructing only the base class and not the derived class.

2. Example:

(1)


  
  #include<iostream>
  using namespace std;

  class Base{
  public:
     Base() {};
    ~Base() {cout << "Output from the destructor of class Base!" << endl;};

    void DoSomething() { cout << "Do something in class Base!" << endl; };
  };

  class Derived : public Base{
  public:
     Derived() {};
    ~Derived() { cout << "Output from the destructor of class Derived!" << endl; };

    void DoSomething() { cout << "Do something in class Derived!" << endl; };
  };
  int  main(){ 
     Derived* p = new Derived;
     p->DoSomething();
     delete p;
     return 0;
   }

Result:

Do something in class Derived!                    

Output from the destructor of class Derived!

Output from the destructor of class Base!  

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

(2)


   #include<iostream>
  using namespace std;

  class Base{
  public:
     Base() {};
    ~Base() {cout << "Output from the destructor of class Base!" << endl;};

    void DoSomething() { cout << "Do something in class Base!" << endl; };
  };

  class Derived : public Base{
  public:
     Derived() {};
    ~Derived() { cout << "Output from the destructor of class Derived!" << endl; };

    void DoSomething() { cout << "Do something in class Derived!" << endl; };
  };
  int  main(){ 
     Base* p = new Derived;
     p->DoSomething();
     delete p;
     return 0;
   }

Results:

Do something in class ClxBase!
Output from the destructor of class ClxBase!

In       code, the destructor of the base class is also not a virtual function. The difference is that in 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: only the resources of the base class are released, but the destructor of the inherited class is not called. Calling the DoSomething() function also performs functions defined by the base class.

      in general, such deletion can only delete base class objects, but not subclass objects, forming the image of deletion half, resulting in memory leak.

In public inheritance, base class operations on derived classes and their objects affect only those members inherited from the base class. If you want to manipulate non-inherited members with a base class, define the function of the base class as a virtual function. The destructor should do the same: if it wants to redefine or create new members and objects in a destructor class, it should also declare virtual.

(3)


  #include<iostream>
  using namespace std;

  class Base{
  public:
     Base() {};
    virtual ~Base() {cout << "Output from the destructor of class Base!" << endl;};

    virtual void DoSomething() { cout << "Do something in class Base!" << endl; };
  };

  class Derived : public Base{
  public:
     Derived() {};
    ~Derived() { cout << "Output from the destructor of class Derived!" << endl; };

    void DoSomething() { cout << "Do something in class Derived!" << endl; };
  };
  int  main(){ 
     Base* p = new Derived;
     p->DoSomething();
     delete p;
     return 0;
   }

Results:

Do something in class ClxDerived!
Output from the destructor of class ClxDerived!
Output from the destructor of class ClxBase!

In       code, the destructor of the base class is defined as a virtual function. In 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 to release the resources of the inherited class and then call the destructor of the base class. Calling the DoSomething() function also executes the function defined by the inheritance class.

3. Conclusion:

A base class pointer can point to an object of a derived class (polymorphism) if the pointer delete p is deleted. The destructor of the derived class that the pointer points to is called, and the destructor of the derived class automatically calls the destructor of the base class, so that the entire object of the derived class is released. If the destructor is not declared as a virtual function, the compiler implements a static binding, and only calls the destructor of the base class but not the destructor of the derived class when the pointer to the base class is deleted, thus resulting in incomplete destructor of the derived class object. Therefore, it is necessary to declare destructors as virtual functions.


Related articles: