#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();
}