Thursday, April 3, 2008

The Dominance Rule

Scope

The Dominance Rule in this article discusses the rule that disambiguates the name resolution in a virtual inheritance in C++.

Dominance Rule

In a multiple inheritance hierarchy it's possible to have ambiguous meanings to a name(object, function, typedef or enumerator), visible through an inheritance graph. This problem creeps its head irrespective of the inheritance being virtual or non-virtual, unless of course dominance comes as a saviour.

Dominance states that a name resolution in an inheritance hierachy goes bottom up and the specificity is determined by the dynamic type of the object refering the name. In other words a name is dominanting if its defined in both the classes where one class derives from the other, and the one in the derived class dominates.

Case I: In a multiple inheritance scenario where only one of the derived classes B overrides the base class identifier 'name', the definition is available in the most derived object D through two different paths. The first definition is that from the derived class B that overrides the base class A's definition, and the second from the base class A through the alternate path. Here the lookup for 'name is ambiguous as B::name doesn't dominate A::name in the base class C.

No dominance: B::name hides A::name
on one path but not on the other


Case II: In a virtual inheritance scenario where both the derived classes B and C overrides the base class identifier 'name' definition, the same is available in the most derived object D through two different paths. The again is ambiguous.

This is ambiguous as B::name and C::name
hides A::name on respective paths


Case III: Let's consider the case where dominance comes into play. If the scenario in Case I was that of virtual inheritance then the definition of B::name would dominate that of A::name coming from a single shared subobject A. Hence the access would not be ambiguous

B::name dominates A::name


Dominance needs care

Dominance can indeed play a spoil sport if not heeded to. Consider the code snippet below.

class A
{
public:
int x;
typedef int y;
};

class B : public virtual A
{
public:
typedef int x;
int y;
};

class C : public B, public virtual A
{
public:
x y; // Works fine as B::x dominates A::x
// so x acts as typdef, and the
// statement as a declaration.
y x; // Error: Flagged as a compile time error
// as B::y dominates A::y and hence y
// is interpreted as an integer.
};
This example illustrates the prominance of the dominance rule in the name lookup for a virtual inheritance hierarchy. Since the name lookup goes bottom up, the name x and y are resolved as a typedef and and integer respectively. This leads to a correct interpretation for the expression x y, while y x is flagged as a compile time error.

References

[1] Dominance Rule - MSDN
[2] C++ Gotcha #79 - Dominance Issues

What people said... (0)