为什么虚拟析构函数有意义?

时间:2014-01-22 11:01:29

标签: virtual virtual-destructor

我知道他们习惯于获取所谓的子类的析构函数(删除指针时)。 但是背景会发生什么?

我的意思是一个子类继承了它的基类的这个虚析构函数。继承某些东西意味着让我得到一些原样。但在这种情况下,子类不会获得与基类相同的析构函数。 (也许它会变得相同,特别是如果它没有身体)。 关键是,即使子类没有重新定义它,它也会做其他事情。那么这是如何运作的?

我们说(C ++):

class BaseClass{
  int i;
  public:
  virtual ~BaseClass(){}
};

class SubClass: public BaseClass{
  int j;
};

BaseClass* bptr = new SubClass;
delete bprt;

在这种情况下,我们希望程序释放一个SubClass类型的对象需要的内存。也就是说,继承的int i和自己的int j。 如果我们在BaseClass中没有虚拟析构函数,那么将使用BaseClass中的默认生成的析构函数(它有一个空体,在此之后,将删除BaseClass的所有成员并释放内存)。

最大的问题是:BaseClass中的虚拟析构函数将由SubClass继承,但SubClass不会重新定义它。为什么继承的析构函数比它继承的类更多呢? (它在SubClass对象上执行时删除整数i和j)

1 个答案:

答案 0 :(得分:0)

首先,就像new分配内存然后运行构造函数一样,delete将运行析构函数然后释放内存。

当您创建新SubClass时,它首先创建BaseClass并运行其构造函数,然后生成SubClass并运行其构造函数。

当我们调用delete时,解构以相反的顺序发生。首先,Subclass被破坏,然后是BaseClass

注意,首先这与其他虚函数不同 - 只调用一个被覆盖函数的实例。析构函数很特殊。

如果BaseClass不是虚拟的,那么当您调用delete bprt;时,只会调用BaseClass析构函数。这很糟糕。

在你的情况下,你有一个虚拟的基础析构函数,并且没有显式编写自己的(并且你没有让编译器为你生成一个),所以编译器会为你生成一个。见here

为什么这么麻烦?因为析构函数将在delete new ed对象时被调用,或者它超出范围。是否“做得更多” - 不,不是在这种情况下。