我正在编写一个抽象的超类,其中每个方法都将被覆盖。我可以实现一些默认功能,但大多数时候它足以将实现留给子类编写器。
由于几乎所有方法都将被覆盖,我应该多少虚拟,我应该多少作为常规方法离开?在目前的版本中,一切都是虚拟的,但我仍然没有让任何人使用它,所以设计是灵活的。
虚拟功能有哪些优点/缺点?有关这方面的良好阅读材料的链接将不胜感激。
答案 0 :(得分:5)
虚函数调用比非虚函数调用慢,但如果需要运行时多态,则别无选择。虚函数调用具有大致恒定的开销,无论您拥有多少,因此没有什么不利之处。您可以看到许多专业类的设计 - 如IDirect3D9Device-在一个类中有许多很多虚拟方法。
答案 1 :(得分:3)
使用virtual是关于能够使用仅具有抽象类类型的派生类代码
如果你总是掌握物体的确切类型,那么你就不需要虚拟,而你的抽象类无论如何都是无用的。
如果你想通过Abstract&使用你的对象。使用虚函数成员
您可能需要阅读this。
(...因为当标准c ++中存在接口时?)
如果你真的真的想要界面:使用boost interface library
答案 2 :(得分:2)
您想要覆盖的任何方法都应声明为虚拟。
虚拟方法的优点是在这种情况下:
BaseClass * o = new SubClass;
o->MyVirtualMethod();
...将调用SubClass :: MyVirtualMethod()(如果SubClass定义了MyVirtualMethod,则通常是您想要的)。如果该方法是非虚拟的,则会调用BaseClass :: MyVirtualMethod(),因为指针(o)的类型为BaseClass。
虚拟方法的缺点是,与非虚方法相比,调用稍微贵一些(就使用的CPU周期而言)。
答案 3 :(得分:2)
答案已经是你的开场白的一部分了 - 你已经说过每一种方法都会被覆盖。只需创建所有应该可虚拟覆盖的功能,并将其余功能保留为非虚拟功能。
答案 4 :(得分:1)
这被称为interface programming - 它没有任何问题,事实上,它通常是一个好主意!
答案 5 :(得分:1)
虚函数允许您在基类指针上调用方法并获取正确的类行为,而无需知道该对象是基类还是派生类。这就是虚拟功能的“优势”,尽管它实际上是它的本质,也是它们的设计目标。
因此,无论您是否需要此功能,都应该从您的课程的设计和预期用途中清楚明确地看出。它不应该是“嗯,什么是权衡”,而是“没有虚函数,实现将是一个复杂的混乱。”
鉴于此,虚拟功能存在运行时成本,但这绝不应成为决定是否使用它们的因素;与优势相比,成本微不足道。相反,在C ++中使用非虚函数的选项是这样的,如果你知道你不需要它们,你甚至没有那么小的开销。在Java中,所有功能都是虚拟的;没有选择没有它,即使你不需要它,你仍然可以得到它,无论如何,与语言中其他所有内容的运行时开销相比,它几乎不需要任何费用。
答案 6 :(得分:0)
如果要覆盖所有内容,为什么不将其作为接口实现呢?
答案 7 :(得分:0)
使用尽可能少的虚拟方法来完成工作。尝试考虑聚合而不是继承。