9

I've seen a lot examples that illustrate the dangerous of multiple inheritance.

The example is usually like Class B and C extends Class A , Class D extends both B and C.

B and C both override a method from A, say for example, equals();

then when call D.equals(); it doesn't know which one from its parent should be called

provided that equals() is not overridden in D.

From what I can see, isn't Class A in this example redundant? If we remove A from this hierarchy and just look at B and C, if B and C both have method called equals(), then when D extends B and C, it will still have the same problem, so isn't it really a triangle of death?

I am not sure if what I assumed will cause compile time error in some other language.

Hope someone can clarify it for me.

bsiamionau
  • 8,099
  • 4
  • 46
  • 73
grumpynerd
  • 177
  • 7

2 Answers2

2

If D extends B and C and not overrides the method equals(), which is implemented in B and C, there is no ambiguity - D can use B.equals() or C.equals().

With diamond structure on the other hand, if D calls A.equals() and both B and C override it, you don't know which method should be invoked B.equals() or C.equals().

Grisha Weintraub
  • 7,803
  • 1
  • 25
  • 45
  • 1
    Are you saying what you seem to be saying? What if the `equals` methods in `B` and `C` are totally different? If `D` can use `B` _or_ `C`, it appears to me that there _is_ an ambiguity. Which one should be chosen? – paxdiablo May 15 '13 at 06:11
  • I mean there is no ambiguity from the execution's point of view. – Grisha Weintraub May 15 '13 at 06:15
  • Well, now you've lost me. If `B.equals()` returns a decent value and `C.equals()` also returns that value, but after formatting your hard disk, what should `D.equals()` do? In any case, this appears to be a dupe so it should probably be closed. – paxdiablo May 15 '13 at 06:18
  • thanks, from your example, Why D needs to call A.equals()? if D knows which one is to call, why can't it just call B.equals() or C.equals(). so my point is can we just use B,C and D to illustrate this problem. – grumpynerd May 15 '13 at 06:22
  • 1
    @grumpynerd - this is the point of polymorphism. Imagine that you have an array of A objects, during the runtime some will be B's, some D's, etc. So you can call `equals` method and appropriate will be chosen. – Grisha Weintraub May 15 '13 at 06:27
  • @Grisha I understand your point, I think I've found the answer from this link. stackoverflow.com/questions/2064880/diamond-problem The difference is diamond of death won't cause compile error. – grumpynerd May 15 '13 at 06:31
2

You're actually right, there is no need for A to exist at all to show the problems of multiple inheritance.

The following code (the "V of death" as Craig eloquently puts it in a comment) is enough:

#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;
}

If you try to compile this, you get:

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()

However, keep in mind you can explicitly choose which one you want with something like:

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

There's more information on the diamond problem here, including why it's actually a different problem.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • It's strange that people call it "death" since the explicit call syntax `passages.xyzzy::get()` exists and makes your intentions obvious. – nurettin May 15 '13 at 06:12
  • i think i understand it better now, I think this will cause compile error where as diamond example won't cause compile error ,but it will cause run time error ? – grumpynerd May 15 '13 at 06:27