#include <iostream>
using namespace std;
/************************************************************************/
/*
虚析构函数和纯虚析构函数
1.当父类指针或引用指向子类对象时,若子类中数据成员有在堆区申请空间,父类析构函数需要
声明为虚析构函数或纯虚析构函数,析构时子类的析构函数会被调用,堆区空间会被释放,否则子类对象会出现内存泄漏问题
2.纯虚析构函数需要进行声明和类外定义,否则编译器或报错
/************************************************************************/
class Animal
{
public:
Animal()
{
cout<<"Animal构造函数"<<endl;
}
//父类虚成员函数
virtual void speak()
{
cout<<"动物在讲话调用"<<endl;
}
/*
//非虚析构函数,父类指针或引用指向子类对象时,只会调用父类析构函数,导致子类析构函数未调用,堆区内存泄漏
~Animal()
{
cout<<"Animal析构函数调用"<<endl;
}
*/
/* //虚析构函数可以解决子类对象堆区空间未释放问题
//父类指针或引用指向子类对象时,先调用父类构造函数,再调用子类构造函数;析构时,先调用子类析构函数,再调用父类析构函数
virtual ~Animal()
{
cout<<"Animal虚析构函数调用"<<endl;
}
*/
//纯虚析构函数也可以达到虚析构同样效果,不但需要声明,还需要有定义
//因为含有纯虚成员函数的类为抽象类,无法实例化,但析构时先调用子类析构函数,再调用父类析构函数,所有需要析构函数的定义(函数体),即使是纯虚析构函数
virtual ~Animal()=0;
};
Animal::~Animal()
{
cout<<"Animal纯虚析构函数调用"<<endl;
}
class Cat:public Animal
{
public:
//有参构造函数,在堆区申请空间
Cat(string name)
{
cout<<"Cat构造函数调用"<<endl;
m_name = new string(name);
}
virtual void speak()
{
cout<<"猫在讲话"<<endl;
}
~Cat()
{
cout<<"Cat析构函数调用"<<endl;
if (m_name != NULL)
{
delete m_name;
m_name = NULL;
}
}
string *m_name;
};
void dospeak(Animal *pmal)
{
pmal->speak();
delete pmal;
}
void test1()
{
dospeak(new Cat("Tom"));
}
int main()
{
test1();
return 0;
}
C++ 虚析构函数和纯虚析构函数
最新推荐文章于 2026-05-22 15:54:27 发布
本文深入探讨了C++中虚析构函数和纯虚析构函数的概念及应用,特别是在多态环境中如何避免内存泄漏问题。通过具体代码示例,详细解释了父类指针指向子类对象时,虚析构函数和纯虚析构函数如何确保子类析构函数被正确调用,从而释放堆区分配的空间。

463

被折叠的 条评论
为什么被折叠?



