引入
问题:为什么只能释放父类的析构
#include<iostream> using namespace std; class Animal { public: virtual void sleep(){ cout<<"动物在睡觉"<<endl; } Animal() { cout<<"animal构造"<<endl; } ~Animal(){ cout<<"animal析构"<<endl; } }; class Cat:public Animal { public: virtual void sleep(){ cout<<"动物在睡觉"<<endl; } Cat() { cout<<"Cat构造"<<endl; } ~Cat(){ cout<<"Cat析构"<<endl; } }; int main() { Animal *p=new Cat; p->sleep(); delete p; return 0; }
原因:p指向的类型为Animal在没有涉及虚析构的时候只能调用父类的析构函数
解决:虚析构(虚函数)
虚析构
虚析构:在析构函数前加virtual修饰
作用
虚析构作用:通过基类指针、引用释放子类的所有空间。
例
#include<iostream> using namespace std; class Animal { public: virtual void sleep(){ cout<<"动物在睡觉"<<endl; } Animal() { cout<<"animal构造"<<endl; } virtual ~Animal(){ cout<<"animal析构"<<endl; } }; class Cat:public Animal { public: virtual void sleep(){ cout<<"猫在睡觉"<<endl; } Cat() { cout<<"Cat构造"<<endl; } ~Cat(){ cout<<"Cat析构"<<endl; } }; int main() { Animal *p=new Cat; p->sleep(); delete p; return 0; }
深入研究
图解
子类析构调用完,系统会自动调用父类析构
纯虚析构函数
特点
是特殊的虚函数
与普通纯虚函数不同点:纯虚析构函数不仅需要=0,而且需要定义函数体
原因:通过基类指针释放子类对象时,先调用子类析构,再父类析构(如果父类的析构不实现,无法实现调用)