关于C++:如果子类没有非静态成员或析构函数,那么我需要一个虚拟析构函数吗?

Do I need a virtual destructor if descendant classes have no non-static members or destructors?

本问题已经有最佳答案,请猛点这里访问。

我在玩弄文件描述符的类层次结构,其中基类持有一个int并在销毁期间对其调用close,而子类不添加任何虚拟方法或数据成员,只是它们的结构不同(例如,named_file_filedes采用路径并在ctor中使用open初始化基部)或非viRTUAL成员函数(例如,只能在kqueue_filedes上调用kevent)。如果这样,基类是否需要一个虚拟析构函数?子类的大小都是相同的,它们都没有自定义销毁逻辑。标记为c++11,因为这是我要瞄准的标准版本。


如果您打算使用基类指针通过delete销毁派生类对象,则需要virtual析构函数。例如:

1
2
3
4
5
6
7
8
class Foo {};
class Bar : public Foo {}

int main()
{
  Foo* f = new Bar;
  delete f; // << UNDEFINED BEHAVIOR without virtual destructor in base classe
}

如果您需要对象具有多态性,那么您还需要在基中至少有1个virtual方法——例如,如果您打算使用dynamic_cast从基到派生。在这种情况下,通常会提供一个虚拟析构函数。只有一个虚拟析构函数就足以确保类是多态的。


如果通过指向基类的指针来delete派生类,那么无论派生类的外观如何,如果没有虚拟析构函数,行为都将是未定义的。

C++ 11标准,第5.3.5/3页:

If the static type of the object to be deleted is different from its
dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.

但是,如果类的构造函数不同,可以考虑使用派生的替代方法,例如简单的自由函数,如create_named_file()