Why should C + + destructors be virtual functions (learning notes)

Posted by jaquito13 on Sat, 15 Jan 2022 12:37:23 +0100

1. Destructor cannot be overloaded

Reason: the destructor cannot be overloaded because it can only have one and cannot take parameters.

2. Why is the destructor of the base class a virtual function?

When implementing polymorphism, when the derived class is operated with the base class, the situation that only the base class is destructed but not the derived class is prevented during destruction.
The following is transferred from the network: source address http://blog.sina.com.cn/s/blog_7c773cc50100y9hz.html
a. first code

#include<iostream>
using namespace std;
class ClxBase{
public:
    ClxBase() {};
    ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;};

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

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

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

Operation results:

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 not a virtual function. In the main function, use the pointer of the inherited class to operate the members of the inherited class. The process of releasing pointer P is to release the resources of the inherited class first, and then the resources of the base class
b. Second code

#include<iostream>
using namespace std;
class ClxBase{
public:
    ClxBase() {};
    ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;};

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

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

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

Output results:

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

In this code, the destructor of the base class is also not a virtual function. The difference is that in the main function, the pointer of the base class is used to operate the members of the inherited class. The process of releasing 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 executes the functions defined by the base class
In general, such deletion can only delete base class objects, not subclass objects, forming a half deletion image, resulting in memory leakage
In public inheritance, the operation of the base class on the derived class and its objects can only affect the members inherited from the base class If you want to use the base class to operate on non inherited members, you should define this function of the base class as a virtual function
The destructor should naturally do the same: if it wants to destruct redefinitions or new members and objects in subclasses, it should also be declared virtual
c. The third code:

#include<iostream>
using namespace std;
class ClxBase{
public:
    ClxBase() {};
    virtual ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;};
    virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};

class ClxDerived : public ClxBase{
public:
    ClxDerived() {};
    ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };
    void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};

  int   main(){  
  ClxBase *p =  new ClxDerived;
  p->DoSomething();
  delete p;
  return 0;
  }  

Operation results:

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: only the resources of the inherited class are released, and then the destructor of the base class is called Calling the dosomething() function also executes the functions 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 virtual functions are defined in a class, the compiler will add a virtual function table to the class to store virtual function pointers, which will increase the storage space of the class Therefore, destructors are written as virtual functions only when a class is used as a base class

Topics: C++ Polymorphism