子类继承父类:
(1)父类构造函数
(2)子类构造函数
(3)子类析构函数
(4)父类析构函数
不管怎么调用子类结果都是一样的:
//通过父类创建子类
Animal *cat = new Cat();
delete cat;
cat = NULL;
cout<<endl;
//子类自己创建自己
Cat *c = new Cat();
delete c;
c = NULL;
cout<<endl;
//或者非指针的方式
Cat cat1;

(后面少截了一段)
现在子类存在带有指针的类:
父类Animal.hpp:
//
// Created by Administrator on 2021/7/16.
//
#ifndef C__TEST01_ANIMAL_HPP
#define C__TEST01_ANIMAL_HPP
#include "iostream"
class Animal {
public:
    string *name;
public:
    Animal();
    //virtual ~Animal() = 0; //纯虚析构,纯虚析构必须在类外实现
    ~Animal();//没用虚析构的情况
    virtual void doSpeak() = 0;//纯虚函数,相当于java的接口,子类必须重写父类方法
};
Animal::Animal() {
    name = new string("animal");
    cout<<"Animal abstract class construction"<<endl;
}
//为了帮助解决父类释放子类指针的问题
Animal::~Animal() {
    if(name !=NULL)
    {
        delete name;
        name = NULL;
    }
    cout<<"Animal Destructor"<<endl;
}
#endif //C__TEST01_ANIMAL_HPP
子类Cat.hpp:
//
// Created by Administrator on 2021/7/16.
//
#ifndef C__TEST01_CAT_HPP
#define C__TEST01_CAT_HPP
#include "iostream"
#include "Animal.hpp"
class Cat :public Animal{
private:
    string *name;
public:
    Cat();
    ~Cat();
    virtual void doSpeak();
};
Cat::Cat() {
    name = new string("tom");
    cout<<"Cat class construction"<<endl;
}
Cat::~Cat() {
    if(name !=NULL)
    {
        delete name;
        name = NULL;
    }
    cout<<"Cat Destructor"<<endl;
}
void Cat::doSpeak() {
    cout<<name<<"在说话函数"<<endl;
}
#endif //C__TEST01_CAT_HPP
我们再在main中调用:
#include <iostream>
using namespace std;
//类的继承多态
#include "Cat.hpp"
int main() {
    //通过父类创建子类
    Animal *cat = new Cat();
    delete cat;
    cat = NULL;
    cout<<endl;
    //子类自己创建自己
    Cat *c = new Cat();
    delete c;
    c = NULL;
    cout<<endl;
    Cat cat1;
    return 0;
}
结果:

从结果可知:第一个用父类指针new子类, 父类并不能释放子类指针!
但是直接子类new子类就不会出现问题,我们在实际应用中肯定会用父类new子类,所以解决办法就是将父类的析构函数换成纯虚析构或者虚析构函数:
代码只需加个virtual:
//
// Created by Administrator on 2021/7/16.
//
#ifndef C__TEST01_ANIMAL_HPP
#define C__TEST01_ANIMAL_HPP
#include "iostream"
class Animal {
public:
    string *name;
public:
    Animal();
    virtual ~Animal() = 0; //纯虚析构,纯虚析构必须在类外实现
    //~Animal();//没用虚析构的情况
    virtual void doSpeak() = 0;//纯虚函数,相当于java的接口,子类必须重写父类方法
};
Animal::Animal() {
    name = new string("animal");
    cout<<"Animal abstract class construction"<<endl;
}
//为了帮助解决父类释放子类指针的问题
Animal::~Animal() {
    if(name !=NULL)
    {
        delete name;
        name = NULL;
    }
    cout<<"Animal Destructor"<<endl;
}
#endif //C__TEST01_ANIMAL_HPP
再看结果,这样就解决了问题:

(后面少截了一段)
原文:https://www.cnblogs.com/yoshinb/p/15018745.html