C++ C++;,菱形继承,何时何地需要实现纯虚拟?
C++:我有一个基类a和一个纯虚函数f(),然后两个类B和C实际上继承自a,还有一个类D继承自B和C(典型的菱形结构): 在以下情况下,何时何地需要实现f()=0C++ C++;,菱形继承,何时何地需要实现纯虚拟?,c++,inheritance,multiple-inheritance,pure-virtual,C++,Inheritance,Multiple Inheritance,Pure Virtual,C++:我有一个基类a和一个纯虚函数f(),然后两个类B和C实际上继承自a,还有一个类D继承自B和C(典型的菱形结构): 在以下情况下,何时何地需要实现f()=0 B和C都有纯虚函数(->抽象类必须实现继承的纯虚函数吗?) 其中只有一个(bxor C)具有纯虚函数(->另一个仍然必须实现f()?) B和C都没有自己的纯虚拟(->跳过B和C中的实现并将其“传递”给D的可能方式?) 在上述三种情况中,D需要实现f()?在哪些情况下,D可以选择实现f()?在哪些情况下,如果有的话,D不可能实现f()
C
也派生自A
,因此它还应该实现f()
B和C都没有自己的纯虚拟(->跳过B和C中的实现并“通过”到D的可能方式?)
您可以这样做。但是这会阻止像这样单独实例化B
或C
-
A *obj = new B(); // Error
A *obj = new C(); // Error
在上述三种情况中,D需要实现f()?在哪些情况下,D可以选择实现f()?在哪些情况下,D不可能实现f()
f()
可以单独在D
中实现,只要您希望它的所有父类都是抽象的
B和C都有纯虚函数(->抽象类必须实现继承的纯虚函数吗?)
是D
必须实现所有继承的纯虚拟函数。除非类实现了类的所有纯虚函数,否则它将从类本身派生为抽象类 其中只有一个(bxor C)具有纯虚函数(->另一个仍然必须实现f()?)
D
必须实现通过任何层次结构中的基类继承的纯虚拟函数。如果其直接基类未定义纯虚拟函数,则该类也将成为抽象类,除非D
实现继承的纯虚拟函数,否则它也将成为抽象类
B和C都没有自己的纯虚拟(->跳过B和C中的实现并“通过”到D的可能方式?)
D
必须实现它通过A->B
和A-C
继承的纯虚拟函数。注意,在这种情况下B
和C
都是抽象类
在上述三种情况中,D需要实现f()?在哪些情况下,D可以选择实现f()?在哪些情况下,D不可能实现f()
D
需要在所有上述3种条件下实现foo()
,以便能够实例化(非抽象)
结论:
避免使用死亡钻石(Diamond of Death)!除非你真正理解其中的微妙之处。很多人试图使用虚拟继承,但这并不是实现他们的设计想要实现的最合适的方式。在某些情况下,使用虚拟继承的确是必要的,但这是一个重要的缺点truct是由该语言提供的,但更多的时候是以错误的方式使用的。因此,再次访问您的设计以验证您是否真的需要虚拟继承是有意义的 以下可能是一本不错的读物:
唯一的要求是,在“叶”级别(最派生的一个级别),每件事物都有一个实现(可能只有一个),否则,如果在访问图形的点上,在相同的“距离”上有更多的实现,就会产生歧义 所以D必须实现所有尚未实现的东西,或者所有东西都通过不同的路径实现了不止一次(以消除歧义)。 如果某个东西——在D级——仍然没有被实现……D不能被恢复,并且实现被要求是从D派生的to和E -钻石是永恒的-
B
和C
)不需要实现继承的纯虚拟。但是像D
这样的子类需要这样做才能实例化B
和C
将继承纯虚方法,只需重写它即可生成最终的具体类D
。如果B
和C
都虚拟继承,那么D
将实现一次。如果它们没有虚拟继承,那么D
将需要同时覆盖B
和C
版本
A *obj = new B(); // Error
A *obj = new C(); // Error