C++虚析构函数

基类的析构函数如果不声明为虚函数,会导致派生类对象在通过基类指针删除时,只会调用基类的析构函数,无法正确释放派生类资源,引发内存泄漏。设置为虚函数后,可以实现动态绑定,确保正确调用派生类析构函数,从而避免资源泄露。动态绑定使得删除基类指针时能调用到正确的析构函数,解决了内存管理问题。
摘要由CSDN通过智能技术生成

为什么需要将基类析构函数设置为虚函数

我们来观察下面这段代码的表现:

class Occupation
{
public:
	Occupation(){ std::cout << "Occupation()" << std::endl; };
    ~Occupation(){ std::cout << "~Occupation()" << std::endl; };
	void show() { std::cout << "Occupation::show()" << std::endl; }
};

class Student : public Occupation
{
public:
	Student(){ std::cout << "Student()" << std::endl; };
    ~Student(){ std::cout << "~Student()" << std::endl; };
};

int main()
{
    Occupation * p = new Student();
    delete p;
    return 0;
}

编译运行后输出:

Occupation()
Student()
~Occupation()

我们不难发现,派生类对象的析构函数没有被调用,也就是说,派生类对象的资源被泄露。

原因

Occupation * p = new Student();
delete p;

由于基类中析构函数v原始股虚函数,那么这里发生的是静态绑定,也就是说*p的类型是Occupation,所以,当进行delete时,只能调用Occupation类型的析构函数,而不会去调用派生类Student的析构函数。

解决

将基类的析构函数变成虚函数。

class Occupation
{
public:
	Occupation(){ std::cout << "Occupation()" << std::endl; };
    virtual ~Occupation(){ std::cout << "~Occupation()" << std::endl; };
	void show() { std::cout << "Occupation::show()" << std::endl; }
};

编译运行输出:

Occupation()
Student()
~Student()
~Occupation()

当基类的析构函数为虚函数时,派生类的析构函数自动转换成虚函数,而且此时发生的是动态绑定

基类的虚函数表中存在&Occupation::~Occupation,派生类的虚函数表中继承来基类虚函数表中的内容,由于派生类的析构函数自动转换成了虚函数,那么派生类的析构函数覆盖掉虚函数表中基类的构造函数,此时派生类的虚函数表中存在的虚函数是:&Student ::~Student

Occupation * p = new Student();
delete p;

delete p时,由于基类的析构函数是个虚函数,将进行访问RTTI,进行动态绑定,*p指的是Student类对象,那么Student类对象中的RTTI自然也是Student,那么将调用Student类的析构函数,完成派生类资源的释放,并且顺带调用基类析构,释放基类资源

补充

指针p一定是指向派生类堆上new出来的对象,栈上的不会发生资源泄露的问题 !!!! 解决该问题需要发生动态绑定。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值