"根据经验,在C++中使所有方法成为虚拟" - 声音建议?

Lum*_*umi 15 c++ virtual

我刚刚发生了标题中的陈述.完整的报价是:

根据经验,使所有方法都是虚拟的(包括析构函数,而不是构造函数),以避免与遗漏虚拟关键字相关的问题.

我在Wrox的专业C++书中找到了这个.你可以谷歌检查.

有什么事吗?我原以为你只提供选择扩展点,而不是默认的可扩展性.例如,Herb Sutter在2001年发表的一篇文章就这么说了.从那时起,有什么改变发生了戏剧性的规范吗?(请注意,我是一名C++ noob,因此我在过去十年中没有关注过这个问题.)

Sig*_*erm 13

有什么事吗?

建议是不好的,毫无疑问.读这样的东西就足以远离这本书及其作者.

你看,虚拟关键字表示"你可以或应该覆盖这种方法 - 它是为此而设计的".

对于任何非平凡的任务,我无法想象一个合理的类系统,它允许用户(即其他程序员)覆盖每个派生类中的每一个单一方法.只有虚拟方法的基本抽象类是正常的.但是,一旦开始创建派生类,就没有理由将"虚拟"打到所有内容上 - 某些方法不需要是可扩展的.

使一切变为虚拟意味着在代码的任何一点,无论调用哪种方法,你都无法确定该类是否会做你想要的,因为有人可以覆盖你的方法,在此过程中打破它(根据墨菲定律)它会发生).这将使您的代码不可靠,并且难以维护.另一个非常有趣的事情是在构造函数中调用虚方法的方式.基本上,通过遵循这个建议,你牺牲了代码的可读性/可靠性,以换取不做一个非常罕见的错字.在看来,这是不值得的.

相比之下,非虚方法保证无论发生什么,在此代码点,代码将始终按预期工作(不包括尚未发现的错误).也就是别人不会用破碎的替代方法取代你的方法.

这个建议让我想起了一些新手程序员倾向于做的常见错误:他们不是开发能解决问题的简单解决方案,而是分散注意力并尝试使代码具有通用性和可扩展性.其结果是,项目需要更长的时间来完成或永远不会成为完整的 - 因为每一个可能的场景通用的解决方案需要更多的努力/开发时间不是仅在手限于目前的问题的本地化解决方案.

我建议坚持使用墨菲定律KISS原则,而不是遵循这个"虚拟"建议.他们对很好.但是,它们不能保证对其他人都有效.


Sti*_*sis 12

我不同意这个原则.

在过去,一些人担心virtual由于性能问题而过度使用.这仍然有点有效,但在今天的硬件上并没有过多的问题.(请记住,大多数其他语言现在都会受到类似的惩罚.例如,400MHz iPhone 2G使用了Objective C,它会在每次函数调用时产生虚拟方法调用.)

我认为你应该只使用virtual那些想要在子类中覆盖它的方法似乎有用和合理.对我来说,它可以作为其他程序员(或者你未来的自我)的暗示,因为"这是一个子类可以明智地定制行为的地方".如果替换子类中的方法会使实现混乱或奇怪,请不要使用virtual.

此外,对于简单的setter和getter,它可能是一个坏主意,因为它会抑制内联.