【C++】C++中基类的析构函数为什么要用virtual虚析构函数?

正面回答:

当基类的析构函数不是虚函数,并且基类指针指向一个派生类对象,然后通过基类指针来删除这个派生类对象时,如果基类的析构函数不是虚析构函数,那么派生类的析构函数就不会被调用,从而产生内存泄漏

复制代码
#include<iostream>
#include<bits/stdc++.h>
using namespace std;

class A
{
public:
    A()
    {
        cout<<"constructing A"<<endl;
    }
    ~A()
    {
        delete p;
        cout<<"destructing A"<<endl;
    }
private:
    int *p;
};

class B:public A
{
public:
    B()
    {
        cout<<"constructing B"<<endl;
    }
    ~B()
    {
        delete p;
        cout<<"destructing B"<<endl;
    }
private:
    int *p;
};

int main()
{

    A *a=new B();
    delete a;
}
/*
constructing A
constructing B
destructing A
*/
复制代码

分析:只调用了基类A的析构函数,而派生类B的析构函数却没有被调用,这时会产生内存泄漏

如果给基类A的析构函数是虚析构函数,那么便不会产生这个问题

复制代码
#include<iostream>
#include<bits/stdc++.h>
using namespace std;

class A
{
public:
    A()
    {
        cout<<"constructing A"<<endl;
    }
    virtual ~A()
    {
        delete p;
        cout<<"destructing A"<<endl;
    }
private:
    int *p;
};

class B:public A
{
public:
    B()
    {
        cout<<"constructing B"<<endl;
    }
    ~B()
    {
        delete p;
        cout<<"destructing B"<<endl;
    }
private:
    int *p;
};

int main()
{

    A *a=new B();
    delete a;
}
/*
constructing A
constructing B
destructing B
destructing A
*/
复制代码

此时派生类B的析构函数被调用了!内存泄漏的问题得以解决

注意构造函数和析构函数的执行顺序:

派生类构造时:先执行基类的构造函数,然后执行派生类的构造函数

派生类析构时:先执行派生类的析构函数,然后执行基类的析构函

上面内存泄漏产生的必要条件:

1.基类析构函数不是虚析构函数

2.派生类对象的析构函数中有内存需要回收

3.基类指针指向派生类对象,通过删除该基类指针来删除派生类对象

那这种情况下为什么会产生内存泄漏呢?

这种情况下,当删除基类指针指向的派生类对象时不会触发动态绑定,虚函数是动态绑定的基础,现在基类的析构函数不是虚函数,所以不会发生动态绑定,而是静态绑定,指针的静态类型为基类类型,所以delete的时候只会调用基类的析构函数

结论:

人生建议,继承时,基类的析构函数中最好加上virtual。


posted @   西*风  阅读(239)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示