I want to prefer variables from one class in diamond inheritance.
This is the code:
class DiamondBase { protected: int x; };
class DiamondSonA: public DiamondBase {};
class DiamondSonB: public DiamondBase {};
class DiamondGS: public DiamondSonA, public DiamondSonB {
void func() { x = x; }
};
I get an error
error: reference to ‘x’ is ambiguous
I can write address x
in func()
like this B::x
/ C::x
.
But I want somehow to prefer x
from class B
, and call it by x
.
Is it possible?
My main purpose it to tag classes using variables, and the diamond inheritance doesn't let me do it...
Thanks
Deriving from the same class through two different paths is colloquially (and meaninglessly) referred to as "the diamond problem", and the usual response is to use virtual inheritance. Like most conventional wisdom, there's a bit of truth there, but it's basically wrong.
When you derive from a class it's because you want the features of the base type in your derived class. If you derive from the same class twice it's either because you want those features twice or because you want them once.
The code in the question gets features twice, and any code the uses those features has to explicitly call out which of the two base objects to use. That's fine, for example, when the base type is a list node and the derived type is intended to participate in two separate lists.
On the other hand, and in most circumstances, the design calls for a single copy of the base type in all derived classes. In that case, the base type should be inherited virtually in every direct derived class.
So, yes, if the code had made DiamondBase
a virtual base everywhere, the ambiguity errors would not come up. Whether that's the right answer depends on the underlying design.