如果后代类没有非静态成员或析构函数,我是否需要虚拟析构函数

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

本文关键字:析构函数 是否 虚拟 后代 静态成员 如果      更新时间:2023-10-16

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

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

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

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

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

C++11 标准,§5.3.5/3:

如果要删除的对象的静态类型与其 动态类型,静态类型应是要删除的对象的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义。

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