#include<iostream>
#include<string>using namespace std;//虚析构和纯虚析构
class Animal
{
public:Animal(){cout<<"执行Animal的构造函数"<<endl;}~Animal(){cout<<"执行Animal的析构函数"<<endl;}virtual void speak()=0;
};
class Cat:public Animal
{
public:string* m_Name;Cat(string name){cout<<"执行Cat的构造函数"<<endl;// new string(name)是在堆区创建一个内容为name的字符层,并返回该字符层的指针。m_Name = new string(name);}virtual void speak(){cout<<*m_Name<<"小猫在说话"<<endl;}~Cat(){if(m_Name!=NULL){cout<<"执行Cat的析构函数"<<endl;delete m_Name;m_Name = NULL;}}
};
void test01()
{Animal* animal = new Cat("Tom");animal->speak();delete animal;
}int main()
{test01();
}
发现程序没有调用子类Cat的析构函数。
因为我们用父类的指针指向子类Cat,当delete animal;时,父类调用自己的析构函数并不会执行子类的析构函数。
导致子类如果有堆区属性,会出现内存泄漏。
解决方法把父类的析构函数改为虚西狗。
虚析构
virtual ~Animal(){cout<<"执行Animal的析构函数"<<endl;}
纯虚析构
virtual ~Animal() = 0;
运行之后报错,因为纯虚析构只是声明,没有实现。
#include<iostream>
#include<string>using namespace std;//虚析构和纯虚析构
class Animal
{
public:Animal(){cout<<"执行Animal的构造函数"<<endl;}virtual ~Animal() = 0;virtual void speak()=0;
};class Cat:public Animal
{
public:string* m_Name;Cat(string name){cout<<"执行Cat的构造函数"<<endl;// new string(name)是在堆区创建一个内容为name的字符层,并返回该字符层的指针。m_Name = new string(name);}virtual void speak(){cout<<*m_Name<<"小猫在说话"<<endl;}~Cat(){if(m_Name!=NULL){cout<<"执行Cat的析构函数"<<endl;delete m_Name;m_Name = NULL;}}};void test01()
{Animal* animal = new Cat("Tom");animal->speak();delete animal;
}Animal::~Animal()
{cout<<"执行Animal的析构函数"<<endl;
}int main()
{test01();
}