在多态使用的过程中,如果子类有数据开辟到了堆区,那么父类指针或者引用在释放的时候无法调用到子类的析构函数。
解决方法:将父类的析构函数修改成为虚析构或者纯虚析构函数
虚析构和纯虚析构:
- 都可以解决子类堆区数据无法释放的问题
- 都需要具体的函数实现
- 虚析构可以直接在类中实现
- 纯虚析构需要在类外,加上类作用域实现
如果类中有纯虚析构函数,那么该类也属于抽象类,无法实例化对象
一、虚析构
#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;
}
类中包含有纯虚析构的话,那么该类为抽象类,无法实例化对象
**