Fixing Ambiguous Conversion

Started by
3 comments, last by mazelle 15 years, 10 months ago
Need suggestions on fixing an ambiguous conversion. I have the following classes:

class InterfaceA
{
...
};

class InterfaceB
{
...
};

class AbstractA : public InterfaceA
{
...
};

class AbstractB : public AbstractA, public InterfaceB
{
...
};

class Concrete : public AbstractB
{
...
};

// now when I use the following it triggers an ambiguous conversion error:
Concrete someObject;
InterfaceA* interface = &someObject;

I think the ambiguous conversion happens because AbstractA and InterfaceB both inherit from InterfaceA. How do I resolve it such that I could treat Concrete as both an InterfaceA and an InterfaceB? The abstract classes are also needed to modularize common code among subclasses of InterfaceA or InterfaceB. An instance of InterfaceB should also be an InterfaceA (is a). Any design suggestions? Thanks
Advertisement
Quote:Original post by mazelle
*** Source Snippet Removed ***

I think the ambiguous conversion happens because AbstractA and InterfaceB both inherit from InterfaceA.
In your sample code, InterfaceB doesn't inherit from InterfaceA...

If that is the case (i.e. your description is right and your sample is wrong), then you should probably inherit the interface classes using virtual inheritance.
class InterfaceA{...};class InterfaceB : public virtual InterfaceA{...};class AbstractA : public virtual InterfaceA{...};class AbstractB : public AbstractA, public virtual InterfaceB{...};
Ah yes, InterfaceB should inherit from InterfaceA, sorry. Thanks, I'll try that. Though I don't really get using 'public virtual' yet.
Quote:Original post by mazelle
Though I don't really get using 'public virtual' yet.
That's why I gave you a link that explains it ;)

Basically, they way you had it before, you were inheriting from InterfaceA twice, which means the compiler is actually putting two copies of that class in your derived classes.
Hence the ambiguity - when you try and cast it back down to a InterfaceA, the compiler doesn't know which copy of InterfaceA you want to cast to.

Virtual inheritance solves this problem by instructing the compiler to only ever store one copy of the base class even if you inherit it more than once.

If you've ever worked with Java, then Java's extends keyword is comparable to C++'s regular public inheritance, but Java's implements keyword is comparable to C++'s public virtual inheritance.
I have read that site before. The Java equivalent makes it clearer though. It's working now. I just want to add that doing it this way would trigger an inheritance through dominance (methods from AbstractA) warning. I resolved this warning by explicitly adding the virtual methods from InterfaceA to AbstractB.

This topic is closed to new replies.

Advertisement