C ++:我有一个带有纯虚函数f()的基类A,然后两个类B和C几乎从A继承,一个D继承自B和C(典型的钻石结构):< / p>
A f() = 0
v/ \v
B C
\ /
D
在下列情况下,f()= 0的位置和时间需要实现?
对于这类问题还有其他共同建议吗?
感谢。
答案 0 :(得分:1)
B和C都有纯虚函数( - &gt;抽象类必须实现继承的纯虚函数吗?)
是 D
必须实施 ALL 继承的纯虚函数。
除非类实现类的所有纯虚函数,否则它从类本身actas派生为Abstract类。
其中只有一个(B XOR C)有一个纯虚函数( - &gt;另一个还必须实现f()吗?)
D
必须实现它通过任何层次结构中的Base类继承的纯虚函数。如果它的直接Base类没有定义Pure虚函数,那么该类也成为一个Abstract类,除非D
实现继承的纯虚函数,否则它也将变为Abstract。
B和C都没有自己的纯虚拟( - &gt;可能的方法来跳过B和C中的implmentation并将其“传递”到D?)
D
必须实现它通过A->B
&amp;继承的纯虚函数。 A-C
。请注意,在这种情况下,B
和C
都是抽象类。
上述三种情况中的哪一种D需要实现f()?在哪些情况下,它可以选择D来实现f()?在哪些情况下,如果有的话,D不可能实现f()?
D
需要在上述所有3个条件中实现foo()
,才能实现(非抽象)。
结论:
避免死亡之钻!除非你真的了解它涉及的微妙之处。很多人尝试使用虚拟继承,但这并不是实现其设计想要实现的最简单的方法。在某些情况下,虚拟继承的使用确实是必要的,但它仍然是语言提供的重要构造,但更常用于错误的方式。因此,重新访问您的设计一次以验证您是否确实需要虚拟继承是有意义的。
以下可能是一个很好的阅读:
答案 1 :(得分:0)
B和C都有纯虚函数( - &gt;抽象类必须实现继承的纯虚函数吗?
是。从抽象类继承的任何类必须实现虚函数才能实例化。否则它们也会是抽象的。
其中只有一个(B XOR C)有一个纯虚函数( - &gt;另一个还必须实现f()吗?)
由于C
也来自A
,因此它也应该实现f()
。
B和C都没有自己的纯虚拟( - &gt;可能的方法来跳过B和C中的implmentation并将其“传递”到D?)
你可以做到这一点。但这会阻止单独B
或C
的实例化,例如 -
A *obj = new B(); // Error
A *obj = new C(); // Error
上述三种情况中的哪一种D需要实现f()?在哪些情况下,它可以选择D来实现f()?在哪些情况下,如果有的话,D是不可能实现f()?
f()
可以单独在D
中实现,只要您确实希望其所有父类都是抽象的。
答案 2 :(得分:0)
唯一的要求是在“叶子”级别(派生的最多)一切都有一个实现(可能只有一个实现,否则如果你访问图表的点 - 可能会产生歧义 - 在相同的“距离”。
所以D必须实现尚未实现的所有内容,或者所有内容都通过不同的路径实现了多次(消除歧义)。 如果某些东西-at D level-仍然没有实现... D不能被实例化,并且要求实现和E,从D派生。
- 钻石是永恒的 -
答案 3 :(得分:0)
不,抽象类(可能是B
和C
)不需要实现继承的纯虚拟。像D
这样的子类需要这样做才能实例化。
不,再次B
和C
将继承纯虚方法,只需重写它就可以生成最终的具体类。
是的,这会以两种方式之一将实施传递给D
。如果B
和C
都是虚拟继承,那么D
会实现一次。如果它们没有虚拟继承,则D
需要覆盖两个 B
和C
版本的f
具体。
如果D
是抽象的,则永远不需要实现f
。假设您的意思是具体,在所有三种情况下,您都需要覆盖f
中的D
。仅当B
和C
覆盖f
而D
不需要时才会这样做。
仔细观察您的设计并删除钻石继承。在大多数情况下,这是防止所有这些问题的最佳选择。