Figure 21.13 demonstrates the ambiguity that can occur in diamond inheritance. Class Base
(lines 8–12) contains pure virtual
function print
(line 11). Classes DerivedOne
(lines 15–23) and DerivedTwo
(lines 26–34) each publicly inherit from Base
and override function print
. Class DerivedOne
and class DerivedTwo
each contain a base-class subobject—i.e., the members of class Base
in this example.
1 // Fig. 21.13: fig21_13.cpp
2 // Attempting to polymorphically call a function that is
3 // multiply inherited from two base classes.
4 #include <iostream>
5 using namespace std;
6
7 // class Base definition
8 class Base
9 {
10 public:
11 virtual void print() const = 0; // pure virtual
12 }; // end class Base
13
14 // class DerivedOne definition
15 class DerivedOne : public Base
16 {
17 public:
18 // override print function
19 void print() const
20 {
21 cout << "DerivedOne
";
22 } // end function print
23 }; // end class DerivedOne
24
25 // class DerivedTwo definition
26 class DerivedTwo : public Base
27 {
28 public:
29 // override print function
30 void print() const
31 {
32 cout << "DerivedTwo
";
33 } // end function print
34 }; // end class DerivedTwo
35
36 // class Multiple definition
37 class Multiple : public DerivedOne, public DerivedTwo
38 {
39 public:
40 // qualify which version of function print
41 void print() const
42 {
43 DerivedTwo::print();
44 } // end function print
45 }; // end class Multiple
46
47 int main()
48 {
49 Multiple both; // instantiate Multiple object
50 DerivedOne one; // instantiate DerivedOne object
51 DerivedTwo two; // instantiate DerivedTwo object
52 Base *array[ 3 ]; // create array of base-class pointers
53
54 array[ 0 ] = &both; // ERROR--ambiguous
55 array[ 1 ] = &one;
56 array[ 2 ] = &two;
57
58 // polymorphically invoke print
59 for ( int i = 0; i < 3; ++i )
60 array[ i ] -> print();
61 } // end main
Microsoft Visual C++ compiler error message:
c:cpphtp9_examplesch23fig21_13fig21_13.cpp(54) : error C2594: '=' :
ambiguous conversions from 'Multiple *' to 'Base *'
Class Multiple
(lines 37–45) inherits from both class DerivedOne
and class DerivedTwo
. In class Multiple
, function print
is overridden to call DerivedTwo
’s print
(line 43). Notice that we must qualify the print
call with the class name DerivedTwo
to specify which version of print
to call.
Function main
(lines 47–61) declares objects of classes Multiple
(line 49), DerivedOne
(line 50) and DerivedTwo
(line 51). Line 52 declares an array of Base *
pointers. Each array element is initialized with the address of an object (lines 54–56). An error occurs when the address of both
—an object of class Multiple
—is assigned to array[ 0 ]
. The object both
actually contains two subobjects of type Base
, so the compiler does not know which subobject the pointer array[ 0 ]
should point to, and it generates a compilation error indicating an ambiguous conversion.
18.116.65.208