The problem of duplicate subobjects is resolved with virtual
inheritance. When a base class is inherited as virtual
, only one subobject will appear in the derived class—a process called virtual base-class inheritance. Figure 21.14 revises the program of Fig. 21.13 to use a virtual
base class.
1 // Fig. 21.14: fig21_14.cpp
2 // Using virtual base classes.
3 #include <iostream>
4 using namespace std;
5
6 // class Base definition
7 class Base
8 {
9 public:
10 virtual void print() const = 0; // pure virtual
11 }; // end class Base
12
13 // class DerivedOne definition
14 class DerivedOne : virtual public Base
15 {
16 public:
17 // override print function
18 void print() const
19 {
20 cout << "DerivedOne
";
21 } // end function print
22 }; // end DerivedOne class
23
24 // class DerivedTwo definition
25 class DerivedTwo : virtual public Base
26 {
27 public:
28 // override print function
29 void print() const
30 {
31 cout << "DerivedTwo
";
32 } // end function print
33 }; // end DerivedTwo class
34
35 // class Multiple definition
36 class Multiple : public DerivedOne, public DerivedTwo
37 {
38 public:
39 // qualify which version of function print
40 void print() const
41 {
42 DerivedTwo::print();
43 } // end function print
44 }; // end Multiple class
45
46 int main()
47 {
48 Multiple both; // instantiate Multiple object
49 DerivedOne one; // instantiate DerivedOne object
50 DerivedTwo two; // instantiate DerivedTwo object
51
52 // declare array of base-class pointers and initialize
53 // each element to a derived-class type
54 Base *array[ 3 ];
55 array[ 0 ] = &both;
56 array[ 1 ] = &one;
57 array[ 2 ] = &two;
58
59 // polymorphically invoke function print
60 for ( int i = 0; i < 3; ++i )
61 array[ i ]->print();
62 } // end main
DerivedTwo
DerivedOne
DerivedTwo
The key change is that classes DerivedOne
(line 14) and DerivedTwo
(line 25) each inherit from Base
by specifying virtual public Base
. Since both classes inherit from Base
, they each contain a Base subobject. The benefit of virtual inheritance is not clear until class Multiple
inherits from DerivedOne
and DerivedTwo
(line 36). Since each of the base classes used virtual inheritance to inherit class Base
’s members, the compiler ensures that only one Base
subobject is inherited into class Multiple
. This eliminates the ambiguity error generated by the compiler in Fig. 21.13. The compiler now allows the implicit conversion of the derived-class pointer (&both
) to the base-class pointer array[ 0 ]
in line 55 in main
. The for
statement in lines 60–61 polymorphically calls print
for each object.
3.128.226.121