虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方式:将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性:
- 可以解决父类指针释放子类对象
- 都需要有具体的函数实现
虚析构和纯虚析构区别:
- 如果是纯虚析构,该类属于抽象类,无法实例化对象
虚析构语法:virtual ~类名(){}
纯虚析构语法:virtual ~类名() = 0;
类名::~类名(){}
#include <iostream>
#include <string>
using namespace std;
class AbstractAnimal{
public:
AbstractAnimal() {
cout << "AbstractAnimal Constructed" << endl;
}
virtual void Speak() = 0;
//父类析构如果存在,不会走子类析构
//只有将其虚拟化后,才能走子类的析构
//利用虚析构可以解决父类指针释放子类对象不干净的问题
virtual ~AbstractAnimal() = 0;
}; //纯虚析构会解决问题,但是在编译器中
//纯虚析构必须存在,被虚拟化后必须有实现的方式。
AbstractAnimal::~AbstractAnimal() {
//不可是空代码
//必须实现。
cout << "Pure Vitural AbstractAnimal Destructed" << endl;
}
class Cat:public AbstractAnimal{
public:
Cat(string name) {
this->m_Name = new string(name);
cout << "Cat Constructed" << endl;
}
void Speak() {
cout << *m_Name << " is speaking" << endl;
}
string *m_Name;
~Cat() {
if (m_Name != NULL) {
delete m_Name;
m_Name = NULL;
}
cout << "Cat Destructed" << endl;
}
};
void DoSpeak(AbstractAnimal* abs) {
abs->Speak();
delete abs;
}
void example() {
DoSpeak(new Cat("Tom"));
}
int main() {
example();
return 0;
}
总结:
1. 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
2. 如果子类中没有堆区数据,可以不写为虚析构或纯虚析构
3. 拥有纯虚析构函数的类也属于抽象类