为什么不为基类强制执行(C++)虚拟析构函数

nea*_*ise 12 c++ theory compiler-construction oop destructor

默认情况下,析构函数不是虚拟的,在不需要它时不会受到伤害,这很好.

但是在基类派生类场景的情况下,是否有任何用例没有虚拟析构函数?如果没有可能(有意义的话),如果一个类派生自一个定义了公共非虚拟析构函数(或没有析构函数)的基类,编译器就会抱怨.而不只是警告它.

Mic*_*hne 12

您的想法的问题是,可以想象有人使用非虚基类析构函数作为优化(如果您永远不会通过基类指针销毁,那么丢失的虚拟不会伤害您,并且仍然避免vtable入口).

既然可以使用它,那是允许的.我认为可选的编译器警告可能是一个好主意,但不是语言规范中的内容.

  • 以boost :: noncopyable为例.它的意思是继承,但你永远不会转发到该基类并删除,因此它不需要虚拟dtor.并且有一个会迫使很多类包含vtable,否则可以避免 (8认同)
  • @Michael Kohne:然后你应该让析构函数"受保护",以便有人不会无意中使用基类指针进行破坏. (4认同)

Bil*_*eal 8

因为拥有非虚拟析构函数是完全有效的.例如,如果子类仅设计为堆栈分配,则不需要虚拟析构函数.当一个类只应该是装饰器时,为什么要求客户拥有所有的vtbl机器?

当一个类要私有地继承(在条件中实现)时,拥有一个虚拟析构函数也没什么意义.

总而言之,析构函数通常应该是公共的,虚拟的或受保护的,除非一个类不是一个基类.


AnT*_*AnT 5

只有在执行对象的多态破坏时才需要虚拟析构函数delete.反过来,这立即意味着动态分配(new-ed)对象.

如果不动态分配对象,则不需要虚拟析构函数.当不需要基类中的虚析构函数时,这会立即提供无限的用例来源.

如果动态分配对象,但从不以多态方式销毁它们,则不需要虚拟析构函数.当不需要基类中的虚拟描述符时,这会添加另一组用例.