home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
[an error occurred while processing this directive]
Previous Table of Contents Next


// Multiple Inheritance

#include <iostream.h>

class Resistance
        {
        protected:
            int R;
        public:
            Resistance(int r)                   {R = r;}
            virtual void Rout(void)
                  {cout << R << endl;}
        };

class Voltage :  virtual public Resistance
        {
        protected:
            double V;
            double I;
        public:
            Voltage(double v, int r):Resistance(r)
                  {V = v;}
            virtual void CalcI(void)
                  {I = V/R;}
            virtual void Iout(void)
                  {cout << I << endl;}
        };

class Current : virtual public Resistance
        {
        protected:
            double V;
            double I;
        public:
            Current(double i, int r):Resistance(r)
                  {I = i;}
            virtual void Vout(void)
                  {cout << V << endl;}
            virtual void CalcV(void)
                  {V = I*R;}
        };

class OhmsLaw : public Voltage, public Current
    {
    public:
        OhmsLaw(double i, double v, int r)
               :Current(i,r),Voltage(v,r),Resistance(r){ }
    };

main()
{
    OhmsLaw L1(0.02,10,1000);
    L1.CalcV();
    L1.CalcI();
    L1.Rout();
    L1.Vout();
    L1.Iout();
    cout << endl;

    return(0);
}

How It Works

I now invite you to convert the virtual class model in the previous program into a nonvirtual inheritance model by simply removing the keyword virtual from the declarations of Voltage and Current just as before.

class Voltage : public Resistance

class Current : public Resistance

This modification gives rise to the nonvirtual inheritance model shown in Figure 5.29 and this is where the problems arise. Because the derived classes Voltage and Current inherit from a nonvirtual Resistance class, each makes a physical copy of Resistance. At the Voltage and Current class level this does not present a problem because they are separate classes. However, when they are combined into the OhmsLaw class using multiple inheritance, the compiler sees two identical versions of the Resistance class and flags an error.


Figure 5.29  The nonvirtual multiple inheritance model of the OhmsLaw class.

Figure 5.29 shows two references to the Resistance class and they come together in the OhmsLaw class. This is illegal in C++. Two items with exactly the same name cannot exist because the program will refuse to compile. Here is the complete program listing; it is just the code listing from step 7 with the virtual class directives removed. Try out the modification and experience the compilation errors.

// Nonvirtual Multiple Inheritance
// WARNING THIS PROGRAM DOES NOT WORK
// IT IS DESIGNED TO SHOW AN ERROR

#include <iostream.h>

class Resistance
        {
        protected:
            int R;
        public:
            Resistance(int r)
                  {R = r;}
            virtual void Rout(void)
                  {cout << R << endl;}
        };

class Voltage :  public Resistance
        {
        protected:
            double V;
            double I;
        public:
            Voltage(double v, int r):Resistance(r)
                  {V = v;}
            virtual void CalcI(void)
                  {I = V/R;}
            virtual void Iout(void)
                  {cout << I << endl;}
        };

class Current :  public Resistance
        {
        protected:
            double V;
            double I;
        public:
            Current(double i, int r):Resistance(r)
                  {I = i;}
            virtual void Vout(void)
                  {cout << V << endl;}
            virtual void CalcV(void)
                  {V = I*R;}
        };

class OhmsLaw : public Voltage, public Current
    {
    public:
        OhmsLaw(double i, double v, int r)
            :Current(i,r),Voltage(v,r),Resistance(r){ }
    };

main()
{
    OhmsLaw L1(0.02,10,1000);
    L1.CalcV();
    L1.CalcI();
    L1.Rout();
    L1.Vout();
    L1.Iout();
    cout << endl;

    return(0);
}

My compiler gave the following set of error messages. When you see this for the first time it’s quite frightening, but the secret is to make sure that an inherited base class that is later recombined through multiple inheritance is defined as virtual.

Compiling...
Listing5.10e.cpp
F:\How To\Chapter 05\Listing5.10e\Listing5.10e.cpp(47) : error C2614:
   ‘OhmsLaw’ : illegal member initialization: ‘Resistance’ is not a base
   or member
F:\How To\Chapter 05\Listing5.10e\Listing5.10e.cpp(56) : error C2385:
   ‘OhmsLaw::Rout’ is ambiguous
F:\How To\Chapter 05\Listing5.10e\Listing5.10e.cpp(56) : warning C4385: could
   be the ‘Rout’ in base ‘Resistance’ of base ‘Voltage’ of class ‘OhmsLaw’
F:\How To\Chapter 05\Listing5.10e\Listing5.10e.cpp(56) : warning C4385: or the
   ‘Rout’ in base ‘Resistance’ of base ‘Current’ of class ‘OhmsLaw’
Error executing cl.exe.

Listing5.10e.obj - 2 error(s), 2 warning(s)

Comments

Virtual classes can be very confusing and difficult to use. As long as you understand the inheritance model, you can predict where duplication will occur and avoid the problem.

An added bonus is that virtual classes use less memory. Recall that they do not copy the class and make several versions of it; they only refer to the original. Therefore, there is only one copy: the original. In a large application, this memory savings can be quite significant.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.