Multiple inheritance introduces the possibility for names to be inherited along more than one path. The class-member names along these paths are not necessarily unique. These name conflicts are called “ambiguities.”
Any expression that refers to a class member must make an unambiguous reference. The following example shows how ambiguities develop:
// Declare two base classes, A and B.
class A
{
public:
unsigned a;
unsigned b();
};
class B
{
public:
unsigned a(); // Note that class A also has a member "a"
int b(); // and a member "b".
char c;
};
// Define class C as derived from A and B.
class C : public A, public B
{
};
Given the preceding class declarations, code such as the following is ambiguous because it is unclear whether b
refers to the b
in A
or in B
:
C *pc = new C;
pc->b();
Consider the preceding example. Because the name a
is a member of both class A
and class B
, the compiler cannot discern which a
designates the function to be called. Access to a member is ambiguous if it can refer to more than one function, object, type, or enumerator.
The compiler detects ambiguities by performing tests in this order:
When an expression produces an ambiguity through inheritance, you can manually resolve it by qualifying the name in question with its class name. To make the preceding example compile properly with no ambiguities, use code such as:
C *pc = new C;
pc->B::a();
Note When C
is declared, it has the potential to cause errors when B
is referenced in the scope of C
. No error is issued, however, until an unqualified reference to B
is actually made in C
’s scope.