在多态使用的过程中,如果子类有数据开辟到了堆区,那么父类指针或者引用在释放的时候无法调用到子类的析构函数。
解决方法:将父类的析构函数修改成为虚析构或者纯虚析构函数
虚析构和纯虚析构:
- 都可以解决子类堆区数据无法释放的问题
 - 都需要具体的函数实现
- 虚析构可以直接在类中实现
 - 纯虚析构需要在类外,加上类作用域实现
 
 
如果类中有纯虚析构函数,那么该类也属于抽象类,无法实例化对象
一、虚析构
#include <iostream>#include <string>using namespace std;class Animal{public:Animal(){cout << "Animal构造函数的调用" << endl;}virtual ~Animal(){ // 虚析构函数的声明和实现cout << "Animal 析构函数的调用" << endl;}virtual void speak(){cout << "Animal在说话" << endl;}};class Cat:public Animal{public:string* str;Cat(string name){str = new string(name);cout << "Cat的构造函数调用" << endl;}~Cat(){if(str != NULL){cout << "Cat析构函数调用" << endl;delete str;str = NULL;}}void speak(){cout << *str << " 在说话" << endl;}};void doSpeak(){// Animal* animal = new Cat("cat");Animal& animal = *(new Cat("cat"));animal.speak();delete &animal;}int main(){doSpeak();return 0;}
二、纯虚析构
纯虚析构函数是在父类中只有声明,定义需要在父类外部且要加上的父类的作用域符号
#include <iostream>#include <string>using namespace std;class Animal{public:Animal(){cout << "Animal构造函数的调用" << endl;}virtual ~Animal() = 0; // 纯虚析构的声明virtual void speak(){cout << "Animal在说话" << endl;}};Animal::~Animal(){ // 纯虚析构的定义cout << "Animal纯析构函数的调用" << endl;}class Cat:public Animal{public:string* str;Cat(string name){str = new string(name);cout << "Cat的构造函数调用" << endl;}~Cat(){if(str != NULL){cout << "Cat析构函数调用" << endl;delete str;str = NULL;}}void speak(){cout << *str << " 在说话" << endl;}};void doSpeak(){// Animal* animal = new Cat("cat");Animal& animal = *(new Cat("cat"));animal.speak();delete &animal;}int main(){doSpeak();return 0;}
类中包含有纯虚析构的话,那么该类为抽象类,无法实例化对象
**
