为什么钻石是死亡而不是死亡的三角形

时间:2013-05-15 05:45:17

标签: design-patterns inheritance multiple-inheritance

我已经看到很多例子说明了多重继承的危险性。

示例通常类似于B类,C扩展A类,D类扩展B和C.

B和C都覆盖了A中的方法,例如equals();

然后调用D.equals();它不知道应该从其父级中调用哪一个

如果在D中没有覆盖equals()。

从我所看到的,这个例子中的A类不是多余的吗?如果我们从这个层次结构中删除A并且只看B和C,如果B和C都有名为equals()的方法,那么当D扩展B和C时,它仍然会有同样的问题,所以它不是真的死亡三角?

我不确定我所假设的是否会导致其他语言的编译时错误。

希望有人能为我澄清一下。

2 个答案:

答案 0 :(得分:2)

如果D extends B and C并且没有覆盖在B和C中实施的方法equals(),则没有歧义 - D可以使用B.equals()C.equals()

另一方面,如果D调用A.equals()并且B和C都覆盖它,则您不知道应该调用哪个方法B.equals()C.equals()。< / p>

答案 1 :(得分:2)

你实际上是对的,根本不需要存在A来显示多重继承的问题。

以下代码(Craig雄辩地将其作为评论中的“死亡之V”)足够了:

#include <iostream>

class xyzzy {
    public: virtual int get (void) { return 7; }
};

class plugh {
    public: virtual int get (void) { return 42; }
};

class twisty: public xyzzy, public plugh {
};

int main() {
    twisty passages;
    std::cout << passages.get() << '\n';
    return 0;
}

如果你试图编译它,你得到:

testprog.cpp: In function ‘int main()’:
testprog.cpp:16:24: error: request for member ‘get’ is ambiguous
testprog.cpp:8:14: error: candidates are: virtual int plugh::get()
testprog.cpp:4:14: error:                 virtual int xyzzy::get()

但请注意,您可以明确选择您想要的内容,例如:

    std::cout << passages.plugh::get() << '\n';

关于钻石问题的更多信息here,包括为什么它实际上是一个不同的问题。