Reputation: 17
when does ambiguity arise in multiple inheritance?
Upvotes: 0
Views: 2950
Reputation: 113242
When it makes names used unclear
class baseX
{
private:
void* callA();//will never be ambiguous.
protected:
void* callB();
public:
void* callC();
}
class baseY
{
private:
void* callA();//will never be ambiguous.
protected:
void* callB();
public:
void* callC();
}
class derived: public baseX, public baseY
{
void someMethod()
{
void* x = baseX::callB();//not ambiguous
void* y = baseY::callB();//not ambiguous
void* z = callB();//ambiguose
}
}
void someFunction(derived& d)
{
void* x = d.CallC();//ambiguous
}
Ambiguity can also happen when the same class is the base through more than one route:
class Base
{
public void call();
}
class DerivedX : public Base
{
}
class DerivedY : public Base
{
}
class GrandChild : public DerivedX, public DerivedY //What does call() do?
{
}
This can be solved with virtual bases:
class Base
{
public void call();
}
class DerivedX : public virtual Base
{
}
class DerivedY : public virtual Base
{
}
class GrandChild : public DerivedX, public DerivedY //only one "Base" class in inheritance, shared between DerivedX and DerivedY
{
}
Upvotes: 0
Reputation: 8053
When you have replicated base class in several paths of inheritance and you are trying to cast to it or call its member-function.
struct A { };
struct B : A { };
struct C : A { };
struct D : B, C { }; // has replicated A as the base class
D d;
A* a = static_cast<A*>(&d); // oops
The problem has several remedies which depend on the context heavily (using virtual base classes, just refine the aforementioned cast, etc.)
More info here, especially here.
Upvotes: 4
Reputation: 577
One famous example of ambiguity in multiple inheritance is the so-called Diamond Problem.
Summary: "In object-oriented programming languages with multiple inheritance and knowledge organization, the diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. 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?"
You can find details here: Wikipedia: Diamond Problem
Upvotes: 3
Reputation: 131789
struct Base{
void foo(){
}
};
struct Derived1 : public Base{
};
struct Derived2 : public Base{
};
struct Final : public Derived1, public Derived2{
};
int main(){
Final f;
f.foo();
}
See on Ideone. To fix, simply use virtual inheritance:
struct Derived1 : virtual public Base{
};
struct Derived2 : virtual public Base{
};
Another possibility for ambigouty is the following:
struct Base1{
void foo(){
}
};
struct Base2{
void foo(){
}
};
struct Final : public Base1, public Base2{
};
int main(){
Final f;
f.foo();
}
Again, on Ideone. To fix, simple make do the following in Final
:
struct Final : public Base1, public Base2{
using Base1::foo;
// or
// using Base2::foo;
};
Upvotes: 1