首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >什么时候使用虚析构函数

什么时候使用虚析构函数

作者头像
ClearSeve
发布于 2022-02-10 19:05:35
发布于 2022-02-10 19:05:35
1.3K0
举报
文章被收录于专栏:ClearSeveClearSeve

问题

什么时候该定义虚析构函数,为什么要这么做?

回答

当你通过一个基类指针去删除(delete)派生对象的时候,虚析构函数就很用了。

代码语言:javascript
复制
#include <iostream>

using namespace std;

class Base
{
public:
    Base(){
        cout << "Base Constructor Called\n";
    }
    ~Base(){
        cout << "Base Destructor called\n";
    }
};

class Derived1: public Base
{
public:
    Derived1(){
        cout << "Derived constructor called\n";
    }
    ~Derived1(){
        cout << "Derived destructor called\n";
    }
};

int main()
{
    Base *b = new Derived1();
    delete b;
}

注意,我并没有把类 Base 的析构函数定义为虚(virtual)。输出如下:

代码语言:javascript
复制
Base Constructor Called
Derived constructor called
Base Destructor called

我们发现派生类的析构函数并没有调用,这是有问题的,有可能会造成内存泄漏,而解决这个问题的办法就是将 Base 的析构函数定义为虚(virtual),

代码语言:javascript
复制
class Base
{ 
public:
    Base(){
        cout << "Base Constructor Called\n";
    }
    virtual ~Base(){
        cout << "Base Destructor called\n";
    }
};

输出如下:

代码语言:javascript
复制
Base Constructor Called
Derived Constructor called
Derived destructor called
Base destructor called

总结起来就是:当你的程序满足以下任何一项时,都无需定义基类虚拟析构函数,否则你就应该定义为虚,

  1. 这个基类没有派生类
  2. 不在堆(heap)内存实例化
  3. 没有指向派生类的基类指针或引用

对于 1,还是很常见的,有的时候我们只是单纯的写一个类,并没有派生它的打算,那这个时候就无需将它的析构函数定义为虚(virtual)了。

对于 2,基本上是个工程项目都不太可能,哪有一次都不在堆(heap)上实例化对象的,我是没遇到过,肯定是有一些对象必须要堆上实例化的。

对于 3,基本上也不太可能,派生类的存在基本上都会用到它的基类指针和引用。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年1月24日,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 问题
  • 回答
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档