为什么虚函数不能过度使用?
我刚刚读到,我们不应该过度使用虚函数。人们认为,虚拟功能越少,错误就越少,维护也就越少。
由于虚拟功能,会出现什么样的错误和缺点?
我对C++或Java的上下文感兴趣。
我能想到的一个原因是,由于v表查找,虚拟函数可能比普通函数慢。
我刚刚读到,我们不应该过度使用虚函数。人们认为,虚拟功能越少,错误就越少,维护也就越少。
由于虚拟功能,会出现什么样的错误和缺点?
我对C++或Java的上下文感兴趣。
我能想到的一个原因是,由于v表查找,虚拟函数可能比普通函数慢。
你已经发布了一些笼统的声明,我认为大多数务实的程序员会耸耸肩,因为他们被误导或误解了。但是,确实存在反虚拟狂热分子,他们的代码对性能和维护来说可能同样糟糕。
在Java中,默认情况下一切都是虚拟的。说你不应该过度使用虚函数是相当强大的。
在C++中,您必须声明一个函数 virtual,但是在适当的时候使用它们是完全可以接受的。
我刚刚读到,我们不应该过度使用虚函数。
很难定义“过度”...当然,“在适当的时候使用虚函数”是很好的建议。
人们认为,虚拟功能越少,错误就越少,维护也就越少。我无法得到由于虚拟功能而会出现什么样的错误和缺点。
设计不佳的代码很难维护。时期。
如果你是一个库维护者,调试隐藏在高类层次结构中的代码,那么很难跟踪代码实际执行的位置,如果没有强大的IDE的好处,通常很难说出哪个类覆盖了行为。它可能导致在跟踪继承树的文件之间跳来跳去。
因此,有一些经验法则,但都有例外:
现实情况是,虚拟功能非常有用,而这些怀疑的阴影不太可能来自平衡的来源 - 虚拟功能已经被广泛使用了很长时间。更多的新语言采用它们作为默认语言。
虚函数比常规函数稍慢。但这种差异是如此之小,以至于除了最极端的情况之外,在所有情况下都没有区别。
我认为避免虚拟功能的最佳理由是防止接口滥用。
编写开放以进行扩展的类是个好主意,但是有这样的事情太开放了。通过仔细规划哪些函数是虚拟的,您可以控制(和保护)类的扩展方式。
当一个类被扩展时,会出现 bug 和维护问题,以至于它破坏了基类的协定。下面是一个示例:
class Widget
{
private WidgetThing _thing;
public virtual void Initialize()
{
_thing = new WidgetThing();
}
}
class DoubleWidget : Widget
{
private WidgetThing _double;
public override void Initialize()
{
// Whoops! Forgot to call base.Initalize()
_double = new WidgetThing();
}
}
在这里,DoubleWidget 破坏了父类,因为是 null。有一个相当标准的方法可以解决这个问题:Widget._thing
class Widget
{
private WidgetThing _thing;
public void Initialize()
{
_thing = new WidgetThing();
OnInitialize();
}
protected virtual void OnInitialize() { }
}
class DoubleWidget : Widget
{
private WidgetThing _double;
protected override void OnInitialize()
{
_double = new WidgetThing();
}
}
现在,Widget 以后不会遇到这种情况。NullReferenceException