Virtual Base Classes: Virtual Inheritance

 < Day Day Up > 



Pause here for a moment and consider the multiple inheritance example presented in the previous section. When a derived class object of type HourlyEmployee or SalariedEmployee is created in memory so too are their related base class objects created in memory. Every instance of HourlyEmployee will have its very own Employee and Person base class objects. In the context of the previous example this is exactly the object behavior desired. But what happens when a subclass inherits from two separate classes who themselves inherit from a common base class? You may or may not want multiple copies of the base class created in memory. To control the creation of base classes in a multiple inheritance design you use the virtual keyword to denote virtual inheritance so that only one copy of the base class object is created.

Figure 13-16 shows a class diagram with four classes: A, B, C, & D. Class D inherits from classes B and C.

click to expand
Figure 13-16: Class Diagram Showing Common Base Class Inheritance

Classes B and C inherit from class A. Using normal, non-virtual inheritance, when a class D object is created, a class B object will be created along with its class A object. A class C object will also be created along with its class A object. This will result in two class A objects existing in memory at the same time as shown in figure 13-17.


Figure 13-17: Non-Virtual Inheritance Will Result in Multiple Instances of Base Classes

In this example, when a D object is created, it would be desirable to have a B and C object created, but not necessarily desirable to have two copies of an A object. (desirability being a matter of design) The non-virtual inheritance implementation of the class diagram shown in figure 13-16 is given in examples 13-29 through 13-33. In these examples I have used inline functions to save space. All the constructors and destructors do is print simple messages so you can trace object creation.

Listing 13.29: a.h

start example
  1   #ifndef A_H  2   #define A_H  3   #include <iostream>  4   using namespace std;  5  6   class A {  7    public:  8       A(){cout<<"A constructor"<<endl;}  9       virtual ~A(){cout<<"A destructor"<<endl;} 10   }; 11   #endif
end example

Listing 13.30: b.h

start example
  1   #ifndef B_H  2   #define B_H  3   #include "a.h"  4   #include <iostream>  5   using namespace std;  6  7   class B : public A{  8     public:  9        B(){cout<<"B constructor"<<endl;} 10        virtual ~B(){cout<<"B destructor"<<endl;} 11   }; 12   #endif
end example

Listing 13.31: c.h

start example
  1    #ifndef C_H  2    #define C_H  3    #include <iostream>  4    using namespace std;  5    #include "a.h"  6  7    class C : public A{  8     public:  9        C(){cout<<"C constructor"<<endl;} 10        virtual ~C(){cout<<"C destructor"<<endl;} 11    }; 12    #endif
end example

Listing 13.32: d.h

start example
  1    #ifndef D_H  2    #define D_H  3    #include <iostream>  4    using namespace std;  5    #include "b.h"  6    #include "c.h"  7  8    class D :  public B,  public C {  9    public: 10       D(){cout<<"D constructor"<<endl;} 11       virtual ~D(){cout<<"D destructor"<<endl;} 12    }; 13    #endif
end example

Listing 13.33: main.cpp

start example
  1   #include <iostream>  2   #include "d.h"  3  4   int main () {  5      D d;  6       return 0;  7   }
end example

Referring to the code for classes B and C, notice how they publicly inherit from class A in the usual fashion. This is non-virtual inheritance and is the usual form of inheritance you will employ in your design. Class D multiply inherits from class B and C. The creation of a class D object results in an object creation chain reaction as is shown in figure 13-18.

click to expand
Figure 13-18: Results of Running Example 13.33.

To prevent multiple A instances classes B and C must virtually inherit from A. Only the B and C class declarations need be modified. Examples 13.34 and 13.35 give the modified code.

Example 13.34: b.h

start example

click to expand

end example

Example 13.35: c.h

start example

click to expand

end example

Now, when example 13.33 is run again it results in a different output as shown in figure 13-19.

click to expand
Figure 13-19: Results of Running 13.33 Showing Effects of Virtual Inheritance

Figure 13-20 shows graphically the relationship of A, B, C, and D objects in memory when virtual inheritance is used.

click to expand
Figure 13-20: Virtual Inheritance Results in One Instance of A



 < Day Day Up > 



C++ for Artists. The Art, Philosophy, and Science of Object-Oriented Programming
C++ For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504028
EAN: 2147483647
Year: 2003
Pages: 340
Authors: Rick Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net