为什么基类的析构函数应该是虚拟的?

时间:2011-05-03 17:48:34

标签: c++ inheritance

在C ++中:为什么基类的析构函数应该是虚拟的?

5 个答案:

答案 0 :(得分:36)

更好的问题是何时以及为何。您的问题表明您认为所有基类都应该具有虚拟析构函数,这并不完全正确。

这将使得无法应用空基类优化,并且可以将类的大小乘以在公共平台上没有virtual的情况下的16倍。

virtual动态类型为delete的对象由类型为DerivedClass的指针时,需要BaseClass*析构函数。 virtual使编译器在对象中关联信息,使其能够执行派生类析构函数。在这种情况下缺少virtual会导致未定义的行为。

如果您不需要这个,并且您的类仅用作基类,则最好使用析构函数protected,从而以所描述的方式意外地阻止用户delete。 / p>

答案 1 :(得分:8)

您希望它们是虚拟的,以便在销毁对象时自动调用所有子类析构函数,即使它是通过指向基类的指针销毁的。在以下代码中:

class base {
public:
  virtual ~base() { }
};

class derived : public base {
public:
  ~derived() { }  // Inherits the virtual designation
};

int main(void)
{
  base *b = new derived;

  delete b;
}

如果基础析构函数是虚拟的,派生的析构函数将仅

正如Magnus指出的那样,如果你没有利用多态性,你不必这样做。但是,我试图养成将所有析构函数声明为虚拟的习惯。它保护我免受我应该宣称它们是虚拟但忘记这样做的情况。正如约翰尼斯指出的那样,当不需要虚拟指定时,这种习惯可能会造成很小的空间和性能损失。

答案 2 :(得分:4)

对于这样的情况:

class A
{
    virtual ~A();
};

class B:A
{
    ~B();
};

A *a = new B(); //legal, since it's a downcast
delete a; //Unless the destructor is virtual, ~A() is called here instead of ~B().

答案 3 :(得分:3)

除非您使用多态,否则它们不必是虚拟的。如果你确实使用了多态,那么它们必须是虚拟的,以便保证继承类的析构函数被调用,所以继承的类可以进行清理。

答案 4 :(得分:1)

它应该是虚拟的,以确保继承类的析构函数是在运行时实际调用的析构函数,而不是被调用的基类析构函数。