钻石继承

chr*_*rds 13 c++ inheritance diamond-problem

假设类D和E和F都从基类B继承,并且类C继承自D和E.

(i)B类有多少副本出现在C类?

(ii)如何使用虚拟继承改变这种情况?解释你的答案.

(iii)对于许多可能在C++中使用多重继承的情况,Java如何避免需要多重继承?

以下是我目前的一些想法,但我绝不是C++方面的专家!

(i)如果C继承自作为B的子类的D和E,那么D和E在技术上是否是超类的副本?然后,如果C继承自D和E,那意味着C中有2个B副本.

(ii)使用虚拟有点类似于在Java中使用Abstract(我认为).现在给出这个,这意味着在C中不会有多个B副本,因为实例化将被级联到所需的级别.我不确定如何说出我的解释但是说B有一个叫做print()的函数打印"我是B"而C覆盖了这个函数put print"我是C".如果您在没有虚拟的情况下在C上调用print(),则最终打印"我是B",使用虚拟将意味着它将打印"我是C".

(iii)我的想法是Java可以使用接口来避免使用多重继承.您可以实现多个接口,但只能扩展一个类.我不确定还有什么要添加,所以任何输入或相关资源都会有所帮助.

M.M*_*M.M 3

(i)和(iii)是正确的。无论如何,根据我的经验,在 C++ 中,当我使用多重继承时,大多数时候是因为基础是接口(这个概念在 C++ 中没有关键字支持,但它是一个您无论如何都可以执行的概念)。

(ii)的第一句话是正确的,但是你的第二句话谈论的是虚拟函数,这与虚拟继承完全不同。虚拟继承意味着只有一个副本B,并且DE都具有相同的副本作为其基数。函数方面没有区别,但区别在于 的成员变量(和基类)B

如果有一个函数可以打印出B成员变量foo;那么在情况 (ii) 中,该函数总是打印相同的值,因为只有一个foo,但在情况 (i) 中,从基类调用该函数可能会打印与从基类D调用它不同的值。E

“钻石继承”这个术语用两个词概括了这一切,这两个词是一个很好的助记符:)