24.7. Multiple Inheritance
In Chapters 9 and 10, we discussed single inheritance, in which each class is derived from exactly one base class. In C++, a class may be derived from more than one base classa technique known as
in which a derived class inherits the
Good Programming Practice 24.2
Software Engineering Observation 24.4
A common problem with multiple inheritance is that each of the base classes might contain data members or member functions that have the same
Figure 24.7. Demonstrating multiple inheritance Base1.h .
(This item is displayed on pages 1213 - 1214 in the print version)
Figure 24.8. Demonstrating multiple inheritance Base2.h .
(This item is displayed on page 1214 in the print version)
Figure 24.9. Demonstrating multiple inheritance Derived.h .
(This item is displayed on page 1215 in the print version)
Figure 24.10. Demonstrating multiple inheritance Derived.cpp .
(This item is displayed on page 1216 in the print version)
Figure 24.11. Demonstrating multiple inheritance.
(This item is displayed on pages 1216 - 1217 in the print version)
Class Base2 (Fig. 24.8) is similar to class Base1 , except that its protected data is a char named letter (line 20). Like class Base1 , Base2 has a public member function getdata , but this function returns the value of char data member letter .
Class Derived (Figs. 24.924.10) inherits from both class Base1 and class Base2 through multiple inheritance. Class Derived has a private data member of type double named real (line 21), a constructor to initialize all the data of class Derived and a public member function getreal that returns the value of double variable real .
Notice how straightforward it is to
The overloaded stream insertion operator (Fig. 24.10, lines 1823) uses its second parametera reference to a Derived objectto display a Derived object's data. This operator function is a friend of Derived , so operator<< can directly access all of class Derived's protected and private members, including the protected data member value (inherited from class Base1 ), protected data member letter (inherited from class Base2 ) and private data member real (declared in class Derived ).
Now let us examine the main function (Fig. 24.11) that tests the classes in Figs. 24.724.10. Line 13 creates Base1 object base1 and initializes it to the int value 10 , then creates the pointer base1Ptr and initializes it to the null pointer (i.e., 0). Line 14 creates Base2 object base2 and initializes it to the char value 'Z' , then creates the pointer base2Ptr and initializes it to the null pointer. Line 15 creates Derived object derived and initializes it to contain the int value 7 , the char value 'A' and the double value 3.5 .
Lines 1820 display each object's data values. For objects
, we invoke each object's
member function. Even though there are two
functions in this example, the calls are not ambiguous. In line 18, the compiler
Resolving Ambiguity Issues That Arise When a Derived Class Inherits Member Functions of the Same Name from Multiple Base Classes
Lines 2427 output the contents of object derived again by using the get member functions of class Derived . However, there is an ambiguity problem, because this object contains two getdata functions, one inherited from class Base1 and one inherited from class Base2 . This problem is easy to solve by using the binary scope resolution operator. The expression derived.Base1::getData() gets the value of the variable inherited from class Base1 (i.e., the int variable named value ) and derived.Base2::getData() gets the value of the variable inherited from class Base2 (i.e., the char variable named letter ). The double value in real is printed without ambiguity with the call derived.getReal() there are no other member functions with that name in the hierarchy.
Demonstrating the Is-A Relationships in Multiple Inheritance
relationships of single inheritance also apply in multiple-inheritance relationships. To