Virtual Base Classes


Multiple inheritances can cause several problems. For example what happens when the classes: DerivedA and DerivedB are derived from the class: BaseA. Suppose further then that the class: MultiplyDerived has a multiple inheritance from both the classes: DerivedA and DerivedB as depicted in the following graphic:

image from book

The above relationship is called a Diamond Inheritance. An example of this type of inheritance is depicted by the following graphic which shows how iostream is derived from istream and ostream where each of these classes in turn derived from ios:

image from book

As you will recall, the object: anObject of the class: MultiplyDerived will inherit its memory requirements from the parents of its class. However, in this case both of the parents are derived from the same class BaseA. The question is then how does MultiplyDerived inherit its memory requirements from BaseA. Would this class inherit two memory units: one from each of its parents? The answer is yes in this case. Further could the constructors of the child MultiplyDerived be defined so that only one unit of memory for the grandparent is defined? What if the constructor of DerivedA called the constructor of BaseA in one way while the constructor of DerivedB called the constructor of BaseA in a totally different way? How then would the constructor of MultiplyDerived be defined so that both the constructor of DerivedA and the constructor of DerivedB were called. For example see virtual0.cpp. Try to compile this program. Notice that it will not compile. Why not?

In some programs, it may be possible to address this problem by specifying which parent is providing the grandparent's "genes" so to speak. This can be done with the scope specifier operator but this is not recommended as the solution. For example if grandparentMember is being addressed in the child, the specifying parent1::grandparentMember (could be a method) may permit this problem to be overcome. However, there are still problems because the object of MultiplyDerived still has two sets of memory for the data members of BaseA. It is better to use virtual classes to overcome this difficulty.

To have the above example of inheritance not compile is undesirable if multiple inheritances are to be permitted. To solve this problem, the concept of virtual base classes or virtual class inheritances was introduced. (Be careful how the word virtual is used. It is an overloaded word and, as indicated below, it is used with respect to a type of functions as well.) To create a virtual base class, the keyword virtual must appear in the derived class' definition. For example notice how the above example has been modified below:

image from book

 class Account {    protected:      float balance;    public:      Account(float startBalance=0)           {balance = startBalance;}      float showBalance() {return balance;)      void deposit(float money){balance += money;} }; class Stock : virtual public Account {    public:      Stock() : Account(100.00) {}      void calculateInterest() {balance *= 1.06;} }; class Mutual : virtual public Account {    public:      Mutual() : Account(10000.00) {}      void addPremium(float amount){balance +=amount;} }; class Golden : public Stock, public Mutual {    public:      Golden() {} }; 

image from book

The keyword virtual has been added to the definitions of each of the classes Stock and Mutual from which Golden is inherited. See virtual.cpp and notice that it compiles and runs. Notice the size of the objects of each class especially notice the size of the object of the class Golden.

While it is possible to create virtual base classes, many authors recommend that this construct not be used. Some would say that the programmer who needs to use this type of construct has designed the library incorrectly. Regardless of which point of view is correct, the programmer should use this technique infrequently if at all and be careful when it is used. (In the programming language C# this type of extension is not permitted and the need for this type of relationship is handled in a different manner.)

Another problem that can arise with this type of inheritance is when the parents have different access to the grandparent. If the derivations of the parents have different access to the grandparent (the base), then the child has the least restrictive access to the grandparent of either of its parents. For example, if in the above program the class Stock was derived as a protected extension from Account and Mutual was derived as a public extension of Account then the class Golden would be derived as a public extension from the properties of the class Account since the public extension is the least restrictive of the two extensions of its parents.

Try notvirtual.cpp and isvirtaual.cpp to notice the impact virtual inheritance has on multiple inheritances.




Intermediate Business Programming with C++
Intermediate Business Programming with C++
ISBN: 738453099
EAN: N/A
Year: 2007
Pages: 142

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