虚拟析构函数可能是一件坏事吗?

时间:2012-04-23 23:02:38

标签: c++

我总是用虚拟析构函数标记我的类,即使它不需要。除了可能性能小的打击之外,还有一种情况,当你不需要一个虚拟析构函数导致内存错误或可怕的东西时,它会有一个虚拟析构函数吗?

由于

3 个答案:

答案 0 :(得分:16)

使所有类都可扩展是一个基本缺陷。大多数类只是不适合继承,如果你没有预先设计扩展类,那么就没有意义。

这只是误导您的API的用户,他们会将此作为该类有意义地继承的暗示。实际上,这种情况很少发生,并且在最坏的情况下不会带来任何好处或破坏代码。

一旦你继承了一个类,你就会终生安定下来:你无法改变它的界面,你绝不能破坏(隐式!)语义它有。从本质上讲,课程不再是你的。

另一方面,无论如何,继承都被高估了。除了用于公共接口(纯虚拟类)之外,您通常应该更喜欢组合而不是继承。

虚拟析构函数不合需要的另一个更基本的情况是,当您的代码需要POD 时才能工作 - 例如在union中使用它时,当与C代码接口或执行POD特定的优化时(只有POD是blittable,这意味着它们可以非常有效地复制)。 [帽子提示安迪]

关于性能开销的说法:在某些情况下,会创建大量小对象,或者在紧密循环中创建对象。在这些情况下,虚拟析构函数的性能开销可能是一个至关重要的错误。

具有虚拟功能表的类也比没有虚拟功能表的类更大,这也会导致不必要的性能影响。

总而言之,没有令人信服的理由让析构函数虚拟化,并且有一些令人信服的理由不这样做。

答案 1 :(得分:2)

如果你不打算从类中继承(或者如果这个类不是要从中继承),那么将它声明为虚拟是毫无意义的。
另一方面,如果你想以多态方式访问这个类,那么是的,虚拟析构函数是一件好事。

但要准确地回答你的问题,它不会导致任何“可怕的记忆错误”,并且一直将它标记为虚拟,这不会真正伤害到你。

但我认为没有理由一直使用虚拟析构函数。这取决于你。

此外,赫伯的this帖子为此事带来了一些启示。

答案 2 :(得分:0)

不,AFAIK。虚拟析构函数的行为与非虚拟析构函数的行为完全相同(即,虚拟和直接调用调用相同的函数),或者您获得未定义的行为。所以你不能通过将非虚拟析构函数更改为虚拟析构函数来“做一些可怕的事情”。

但是,它可以暴露由代码的其他部分引起的错误,即。当您不小心覆盖对象的虚拟表指针时。