回答
这是一个根本缺陷,使各阶层扩展。大多数类别仅仅是不适合被继承,如果您没有为扩展预先设计类,那么便于这个是没有意义的。
这只是误导您的API的用户谁会将此作为暗示该类可以有意义地继承。事实上,这种情况很少出现,并且不会带来任何好处,或者在最坏的情况下破坏代码。
一旦你做出一个类继承,你用它解决你的余生:你不能改变它的界面,你绝不能打破(隐含!)语义它。本质上,这个班不再是你的。
另一方面,无论如何,继承是被高估的。除了用于公共接口(纯虚拟类)之外,您通常应该更喜欢构造而不是继承。
另一个更基本的情况下的虚拟析构函数是不希望的是当你有的代码需要一个工作 - 例如在一个union
使用它时,与C语言代码的接口或执行时POD-特定的优化时作为(只有POD是blittable,意味着它们可以非常有效地复制)。 [帽尖安迪]
甲字约性能开销:存在其中许多小对象被创建的情况下,或者在紧凑循环中创建的对象。在这些情况下,虚拟析构函数的性能开销可能是一个严重错误。
具有虚拟功能表的类也是比没有类更大的,这也会导致不必要的性能影响。
总而言之,没有令人信服的理由让析构函数变成虚拟的,并且一些令人信服的理由不是。
我同意所有这一切。但更实际的答案可能是因为添加虚拟析构函数会破坏结构的POD性,并且有许多应用程序能够根据其内存内容定义对象,这是设计需求。 – 2012-04-23 23:14:00
@Andy老实说,我甚至没有想到这一点,这是一个很好的理由,值得自己回答。 – 2012-04-23 23:14:57
@我现在已经添加了这个。 – 2012-04-24 07:07:02
如果你不打算从类继承计划(或者如果类不打算继承),那么声明它是虚拟的就没有意义了。另一方面,如果你想多态地访问这个类,那么是的,虚拟析构函数是一件好事。
但是要准确回答你的问题,它不会导致任何“可怕的记忆错误”,并且始终将它标记为虚拟并不能真正伤害你。
但我没有理由一直使用虚拟析构函数。随你便。
另外,由Herb发布的this带来了一些事情。
不,AFAIK。虚拟析构函数的行为与非虚拟行为完全相同(即虚拟和直接调用调用相同的函数),或者您得到未定义的行为。所以你不能通过将非虚拟析构函数改为虚拟函数来“做出糟糕的事情”。
但是,它可以暴露由代码的其他部分引起的错误,即。当你不小心覆盖了对象的虚拟表格指针时。
- 1. 没有虚拟构造函数但是虚拟析构函数
- 2. C++虚拟析构函数
- 3. 虚拟析构函数?
- 4. 在.NET中,一个类可以有虚拟构造函数吗?
- 5. 代表应该有一个虚拟析构函数吗?
- 6. 虚拟析构函数分段错误
- 7. 虚拟析构函数 - 有需要时
- 8. 虚拟析构函数如何工作?
- 9. 没有虚拟方法的虚拟析构函数有什么危害吗?
- 10. 类有虚函数和可访问的非虚拟析构函数
- 11. 模板函数的特化可以是虚拟的吗?
- 12. 在C++中,构造函数和析构函数可以是内联函数吗?
- 13. 以下哪种情况下需要虚拟析构函数?
- 14. 虚拟析构函数是否被继承?
- 15. 为什么`boost :: multi_array_ref`的析构函数是非虚拟的?
- 16. 升压“析构函数不是虚拟的”错误在MSVC 11
- 17. 为什么QWidget的析构函数不是虚拟的?
- 18. 每个班级都应该有一个虚拟析构函数吗?
- 19. 在一行声明并实现纯虚拟析构函数?
- 20. 使用虚拟析构函数,我需要为每个子类明确声明一个虚拟析构函数吗?
- 21. 可以从NHibernate实体的构造函数中调用虚拟属性吗?
- 22. 如果基类析构函数是虚拟的,是否需要派生类析构函数定义?
- 23. C#泛型可以用来隐藏虚拟函数调用吗?
- 24. 虚拟函数还是虚拟方法,哪一个合适?
- 25. 为什么我们有一个虚析构函数,而不是在C虚拟构造++?
- 26. 长方法是一件坏事吗?
- 27. 应该可以初始化具有未覆盖的纯虚拟析构函数的类吗?
- 28. 虚拟函数C++:虚拟函数已经有一个主体
- 29. 虚拟机中可以使用dotTrace吗?
- 30. Rails 4虚拟记录(不是虚拟属性) - 可能吗?
Konrad采取了这个。 *一个*副作用是它可以消耗大量的二进制大小并增加编译时间,特别是当没有一个类的虚拟外行定义时。 – justin 2012-04-23 23:25:08