Deitel & Associates, Inc. Logo

Back to
digg.png delicious.png blinkit.png furl.png
C++ How to Program, 5/e

© 2005
pages: 1500
Buy the Book!
Amazon logo
InformIT logo

Our C++ Multiple Inheritance tutorial introduced C++'s multiple inheritance capabilities. This tutorial continues our presentation of multiple inheritance by investigating the so-called diamond inheritance problem. We discuss how this problem can be solved with virtual base classes. This tutorial is intended for students and developers who are already familiar with multiple inheritance in C++ or who have read our tutorial on Multiple Inheritance.

Download the code examples for this tutorial.

[Note: This tutorial is an excerpt (Section 24.8) of Chapter 24, Other Topics, from our textbook C++ How to Program, 5/e. These tutorials may refer to other chapters or sections of the book that are not included here. Permission Information: Deitel, Harvey M. and Paul J., C++ HOW TO PROGRAM, ©2005, pp.1218-1222. Electronically reproduced by permission of Pearson Education, Inc., Upper Saddle River, New Jersey.]

24.8 Multiple Inheritance and virtual Base Classes (Continued)

Eliminating Duplicate Subobjects with virtual Base-Class Inheritance

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. FFigure 24.14 revises the program of Fig. 24.13 to use a virtual base class.

 1  // Fig. 24.14: fig24_14.cpp
 2  // Using virtual base classes.
 3  #include <iostream>
 4  using std::cout;
 5  using std::endl;
 7  // class Base definition
 8  class Base
 9  {
10  public:
11     virtual void print() const = 0; // pure virtual
12  }; // end class Base
14  // class DerivedOne definition
15  class DerivedOne : virtual public Base
16  {
17  public:
18     // override print function
19     void print() const
20     {
21        cout << "DerivedOne\n";
22     } // end function print
23  }; // end DerivedOne class
25  // class DerivedTwo definition
26  class DerivedTwo : virtual public Base
27  {
28  public:
29     // override print function
30     void print() const
31     {
32        cout << "DerivedTwo\n";
33     } // end function print
34  }; // end DerivedTwo class
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 Multiple class
47  int main()
48  {
49     Multiple both; // instantiate Multiple object
50     DerivedOne one; // instantiate DerivedOne object
51     DerivedTwo two; // instantiate DerivedTwo object
53     // declare array of base-class pointers and initialize
54     // each element to a derived-class type
55     Base *array[ 3 ];
56     array[ 0 ] = &both;
57     array[ 1 ] = &one;
58     array[ 2 ] = &two;
60     // polymorphically invoke function print
61     for ( int i = 0; i < 3; i++ )
62        array[ i ]->print();
64     return 0;
65  } // end main
 Fig. 24.14  Using virtual base classes.



The key change in the program is that classes DerivedOne (line 15) and DerivedTwo (line 26) each inherit from class Base by specifying virtual public Base. Since both of these classes inherit from Base, they each contain a Base subobject. The benefit of virtual inheritance is not clear until class Multiple inherits from both DerivedOne and DerivedTwo (line 37). Since each of the base classes used virtual inheritance to inherit class Base’s members, the compiler ensures that only one subobject of type Base is inherited into class Multiple. This eliminates the ambiguity error generated by the compiler in Fig. 24.13. The compiler now allows the implicit conversion of the derived-class pointer (&both) to the base-class pointer array[ 0 ] at line 56 in main. The for statement at lines 61–62 polymorphically calls print for each object.

Constructors in Multiple-Inheritance Hierarchies with virtual Base Classes

Implementing hierarchies with virtual base classes is simpler if default constructors are used for the base classes. The examples in Fig. 24.13 and Fig. 24.14 use compiler-generated default constructors. If a virtual base class provides a constructor that requires arguments, the implementation of the derived classes becomes more complicated, because the most derived class must explicitly invoke the virtual base class’s constructor to initialize the members inherited from the virtual base class.
Software Engineering Observation
Software Engineering Observation 24.5
Providing a default constructor for virtual base classes simplifies hierarchy design.

Additional Information on Multiple Inheritance

Multiple inheritance is a complex topic typically covered in more advanced C++ texts. The following URLs provide additional information about multiple inheritance.
A tutorial on multiple inheritance with a detailed example.
Provides technical tips that explain several issues regarding multiple inheritance.
Part of the C++ FAQ Lite. Provides a detailed technical explanation of multiple inheritance and virtual inheritance.

Additional Pages in this Tutorial:   Page 1 | 2

Other tutorials on this topicl:
24.7 Multiple Inheritance
24.8 Multiple Inheritance and virtual Base Classes (You are here).

Tutorial Index