In-depth analysis of virtual destructors and pure virtual destructors

question:

1. How to solve the problem that when using polymorphism , when there are attributes in the subclass open to the heap area , the parent class pointer cannot be called to the subclass destructor code when it is released? ? ?


2. How much do you know about virtual destructor and pure virtual destructor ? ? ?


Why is Cat's destructor not called in the following example?

#include<iostream>
#include<string>
using namespace std;
//动物类
class Animal{
    public:
    Animal(){
        cout<<"Animal的构造函数调用"<<endl;
    }
    //纯虚函数
    virtual void speak()=0;
    ~Animal(){
        cout<<"Animal的析构函数调用"<<endl;
    }
};
//猫类
class Cat:public Animal{
    public:
    Cat(string name){
        cout<<"Cat的构造函数调用"<<endl;
        m_Name=new string(name);//数据创建在堆区,用指针属性维护
    }


    //重写虚函数
    virtual void speak(){
        cout<<*m_Name<<"小猫在说话"<<endl;
    }

    ~Cat(){
        if(m_Name!=NULL){
            cout<<"Cat的析构函数调用"<<endl;
            delete m_Name;
            m_Name=NULL;
        }
    }

    string *m_Name;//为了让数据创建在堆区
};

int main()
{
    Animal *abs=new Cat("Tom");
    abs->speak();
    delete abs;
    return 0;
}

operation result:

Animal's constructor call
Cat's constructor call
Tom the cat talking
Animal's destructor call

reason:

When polymorphism is used, if there is an attribute in the subclass that is allocated to the heap area, the pointer of the parent class cannot be called to the destructor code of the subclass when it is released! There may be a memory leak problem.

Solution:

Change the destructor in the parent class to virtual destructor or pure virtual destructor.


~~This is the dividing line~~

Common features of virtual destructors and pure virtual destructors :

  • The parent class pointer can be resolved to release the child class object
  • need to have specific function implementation

The difference between virtual destructor and pure virtual destructor :

  • If it is pure virtual destructor, the class is abstract and cannot instantiate objects

Method 1: Change the destructor in the parent class to a virtual destructor

The use of virtual destructor can solve the situation that the parent class pointer is not clean to release the child class object. 

Method 2: Change the destructor in the parent class to a pure virtual destructor, and there must be a function implementation process.

A class with pure virtual destructor is called abstract class and cannot instantiate objects

operation result:

Animal's constructor calls
Cat's constructor calls
Tom Kitten is talking
Cat's destructor calls
Animal's destructor calls 

Usage time: When the subclass has data application in the heap area, the parent class pointer cannot release the subclass object.

Code:

#include<iostream>
#include<string>
using namespace std;
//动物类
class Animal{
    public:
    Animal(){
        cout<<"Animal的构造函数调用"<<endl;
    }
    //纯虚函数
    virtual void speak()=0;
   
    //纯虚析构  必须要有函数的具体实现->父类中可能有需要释放的数据
    virtual ~Animal()=0;
};

Animal::~Animal(){
    cout<<"Animal的析构函数调用"<<endl;
}

//猫类
class Cat:public Animal{
    public:
    Cat(string name){
        cout<<"Cat的构造函数调用"<<endl;
        m_Name=new string(name);//数据创建在堆区,用指针属性维护
    }


    //重写虚函数
    virtual void speak(){
        cout<<*m_Name<<"小猫在说话"<<endl;
    }

    ~Cat(){
        if(m_Name!=NULL){
            cout<<"Cat的析构函数调用"<<endl;
            delete m_Name;
            m_Name=NULL;
        }
    }

    string *m_Name;//为了让数据创建在堆区
};

int main()
{
    Animal *abs=new Cat("Tom");
    abs->speak();
    delete abs;
    return 0;
}

Guess you like

Origin blog.csdn.net/zhangxia_/article/details/121357965