Talk:Diamond problem

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

Ruby[edit]

This doesn't seem right, I'm pretty sure that Ruby only supports single inheritance. —Preceding unsigned comment added by 129.97.190.60 (talk) 13:50, 3 April 2009 (UTC)[reply]


CiteSeer?[edit]

Someone who knows the policy on this kind of thing might consider linking to the CiteSeer version of the article mentioned at the bottom: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.73.6034&rep=rep1&type=pdf —Preceding unsigned comment added by 76.27.56.101 (talk) 06:16, 3 May 2009 (UTC)[reply]

C++[edit]

"C++ takes special care to only create one A object, and uses of A's members work correctly"

What does "correctly" mean? g++ complains as follows:

#include <iostream>

class Animal 
{
	public:
	virtual void eat()
	{
		std::cout << "Animal" << std::endl;
	}
};
 
class Mammal : public virtual Animal 
{
	public:
	virtual void eat()
	{
		std::cout << "Mammal" << std::endl;
	}
};
 
class WingedAnimal : public virtual Animal 
{
	public:
	virtual void eat()
	{
		std::cout << "WingedAnimal" << std::endl;
	}
};
 
// A bat is a winged mammal
class Bat : public WingedAnimal, public Mammal {};

int main()
{
	Bat bat;
	bat.eat();
}

multiple inh.cpp:31: error: no unique final overrider for 'virtual void Animal::eat()' in 'Bat'
multiple inh.cpp: In function 'int main()':
multiple inh.cpp:36: error: request for member 'eat' is ambiguous
multiple inh.cpp:15: error: candidates are: virtual void Mammal::eat()
multiple inh.cpp:24: error:                 virtual void WingedAnimal::eat()

Please clarify, thanks. 118.7.198.171 (talk) 08:19, 14 June 2009 (UTC)[reply]

Is there something that you are trying to do here? Is there a real question you are asking? WPcorrector (talk) 07:19, 10 November 2011 (UTC)[reply]
It looks like it's treating things "correctly" in that it is ambiguous what bat.eat() should be. If Animal had another virtual function that wasn't ambiguously overridden by other classes, then I think it would compile and work fine. For example if you had Animal::foo() which was overridden by Mammal but not by WingedAnimal, then calling bat.foo() would be fine. The error here could be resolved by providing Bat::eat(), I believe. That could just call WingedAnimal::eat(), but as it is it is ambiguous. —Ben FrantzDale (talk) 13:07, 10 November 2011 (UTC)[reply]

Why does the grandparent class matter?[edit]

I don't understand why the grandparent class (A in the introduction example) matters at all. Seems like it only makes it more complicated to explain. I would explain it like this:

The diamond problem is an ambiguity that arises when a subclass inherits from two parent classes that both define the same method name in two different ways.

Is this not the diamond problem?

Fresheneesz (talk) 06:21, 26 April 2010 (UTC)[reply]

The problem with diamond hierarchy tree is also that the data members of the base class is duplicated, (perhaps the article should be clarified), this arises when the A class is present, in any case if A isn't there it doesn't look like a diamond and the name makes no sense :o) Motti (talk) 09:32, 2 May 2010 (UTC)[reply]
My problem with that idea (that the members of the base class are duplicated) is: when has such a case caused an ambiguity in a real language? I contend that there is no interpretation of multiple inheritance that would make such member duplication make sense in a language. Am I simply wrong? In my understanding, the diamond problem is a name collision problem at its root. Fresheneesz (talk) 23:56, 2 May 2010 (UTC)[reply]
"an ambiguity in a real language?" which language? what is a "real" language? (as opposed to "imaginary"? "that would make such member duplication make sense in a language" In the real C++ language, base class sub-objects are duplicated! "the diamond problem is a name collision problem at its root" Nonsense. WPcorrector (talk) 07:01, 10 November 2011 (UTC)[reply]
By "real language" i mean a defined language that is self-consistent (ie a language that doesn't have contradictory semantics) - ie any language that could possibly exist, be it a pseudo language or an implemented language like C. Fresheneesz (talk) 03:49, 8 February 2012 (UTC)[reply]
"The problem with diamond hierarchy tree is also that the data members of the base class is duplicated" the data members are duplicated, the function members are duplicated, everything is duplicated because the base class is duplicated. This is not the problem. The problem is only when you didn't want to duplicate the base class, and forgot to use virtual. WPcorrector (talk) 07:01, 10 November 2011 (UTC)[reply]

Fresheneesz, would you agree that a "name collision problem" is one that can be solved by changing a name in a declaration to a different unique name, and all uses of it (or several names in case of multiple collisions)?

Then the diamond problem is absolutely not a "name collision problem": you could change the name of class A to class uniq_nreybtothfesh, the name of the class will still "collide" with itself.

The diamond problem should not be confused with "I have two declarations with the same name in different scopes, and both are visible in this scope" as in:

namespace A {
	int foo;
}

namespace B {
	int foo;
}

using namespace A;
using namespace B;

int main () {
	foo; // which foo?
}

WPcorrector (talk) 01:58, 5 August 2012 (UTC)[reply]

"Deadly Diamond of Death"[edit]

This problem is often referred to as the "Deadly Diamond of Death". Though this is primarily in reference specifically to C++, and most common in the Java community. But it's a common enough term (9 million+ Google hits) that it probably deserves mention in the article. Lurlock (talk) 20:24, 31 January 2012 (UTC)[reply]

Mentioned. The earliest definitive citation i could find is Robert C. Martin's C++/Java comparison from 1997, but if someone knows an earlier or better citation, please add it. --Piet Delport (talk) 12:09, 9 March 2012 (UTC)[reply]

The definition[edit]

Consider this line : "If a method in D calls a method defined in A (and does not override the method), and B and C have overridden that method differently, then from which class does it inherit: B, or C?"

Before looking into whether this is the diamond problem or not, let's verify whether this is a problem or not.

If you want to call a method(say "foo", inherited and overriden by B and C also) of class A from a method of class D (A, B, C, D as in the definition),

void D::example_function(){
    A::foo();
}

works correctly.

The correct definition should be "If D calls a method defined in A ...".

The problem is that we cannot do

d.foo()

where d is an object of type D. This is the diamond problem. — Preceding unsigned comment added by Swagatata (talkcontribs) 14:49, 7 February 2012 (UTC)[reply]

The diamond problem is not one of ambiguity[edit]

I was thinking and reading about multiple inheritance today, and it occurred to me that the diamond problem is not a problem of ambiguity. All languages that have multiple inheritance easily solve the problem of "which method to call" (though those solutions may have their own problems).

So whats the problem? The problem specifically manifests where both B's method and C's method call A's method (via super or however). Both methods may potentially call A's method anywhere within them, and with any arguments, causing C's method's call to A to duplicate all, some, or none of the work done by B's method's call to A if they were both called by D's overridding method.

Is this a correct assessment of the problem, or is it related but not the diamond problem? Fresheneesz (talk) 04:34, 8 February 2012 (UTC)[reply]

In general, the problem is that code may fail to perform as programmer intended. For programmers who do not understand virtual vs. non-virtual inheritance, it is often the case that code does not perform as intended when using multiple inheritance of the same class. WPcorrector (talk) 01:44, 5 August 2012 (UTC)[reply]