何时适合使用虚拟方法?

Max*_*xpm 20 c++ oop methods virtual

我知道虚方法允许派生类重写从基类继承的方法.何时使用虚拟方法是否合适/不合适?并不总是知道一个班级是否会被分类.一切都应该是虚拟的,只是"以防万一?" 或者这会导致很大的开销吗?

Jor*_*ans 10

首先是一个略显迂腐的评论 - 在C++标准中我们称它们为成员函数,而不是方法,尽管这两个术语是等价的.

我认为有两个原因不能使成员函数成为虚拟的.

  • "YAGNI" - "你不需要它".如果您不确定某个类是否会派生出来,则假设它不会,并且不会将成员函数设置为虚拟.顺便说一句,没有什么比"非虚拟析构函数"更能说明"不要来自我".这也与意图有关.如果您不打算以多态方式使用该类,请不要将任何内容虚拟化.如果你任意虚拟成员,你就会招致Liskov替换原则的滥用,这些错误类别很难追查和解决.
  • 性能/内存占用.没有虚拟成员函数的类不需要VTable(虚拟表,用于通过基类指针重定向多态调用),因此(可能)占用内存中较少的空间.此外,直接成员函数调用(可能)比虚拟成员函数调用更快.不要通过先发制人地使成员函数变为虚拟来过早地使你的课程变得悲观.


Mar*_*k B 7

当你设计一个类时,你应该对它是否代表一个接口(在这种情况下你标记适当的可重写方法和析构函数虚拟)有一个很好的想法,或者它的目的是按原样使用,可能与其他对象组合或组合.

换句话说,你的课程意图应该是你的指导.使一切虚拟化通常是过度的,有时会误导哪些方法旨在支持运行时多态性.


Mat*_* M. 5

这是一个棘手的问题。但是要遵循一些准则/经验法则。

  1. 只要您不需要从类派生,就不要编写任何virtual方法,一旦需要派生,就只virtual需要在子类中自定义那些方法即可。
  2. 如果类具有virtual方法,则析构函数应为virtual(讨论结束)。
  3. 尝试遵循NVI(非虚拟接口)习惯用法,使virtual方法不公开,并提供负责评估前后条件的公共包装器,以使派生类不会意外破坏它们。

我认为这些很简单。我绝对放过反射的ABI部分,它仅在提供DLL时有用。