Click Here!
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


How It Works

The basic functionality of Triangle is defined in the Triangle class. Inline definitions are used for the member functions because they are very short and simple. The Prism class inherits the characteristics of the Triangle base class and adds its own enhancements to it. These enhancements consist of a third member variable named depth and a member function named CalcArea. This new version of CalcArea is used to calculate the area of a prism rather than a triangle and is said to override the definition of CalcArea in the Triangle base class. When an instance of Prism is created, it uses the CalcArea associated with the Prism class. If an instance of Triangle is created, it uses the CalcArea associated with the Triangle class.

The main section of the following program creates an instance of Prism named test and gives it three values. Invisible to the programmer, the first parameter is acted on by the Prism constructor and the other two parameters are passed on to the Triangle constructor. Had a suitable Triangle constructor not been available a compilation error would have been flagged.

The rest of the program simply calculates the volume of the prism and displays the result to the screen. Here is the full listing.

// Inheritance

#include <iostream.h>

class Triangle    {
            protected:
                double base;
                double height;
                double area;
            public:
                Triangle(double b, double h)
                {
                    base = b;
                    height = h;
                }
                void CalcArea(void)
                {
                    area = (base * height) / 2;
                }
                void ShowArea(void)
                {
                    cout << “The area is : “
<< area << endl;
}
};

class Prism:public Triangle
{
    protected:
        double depth;
    public:
    Prism(double d, double b, double h):Triangle(b,h)
    {
        depth = d;
    }
    void CalcArea(void)
    {
        area = (base * height * depth) / 2;
     }
};

main()
{
    Prism test(3,5,10);
    test.CalcArea();
    test.ShowArea();
    return(0);
}

Comments

Confusion can arise when an appropriate constructor buried deep in the inheritance model cannot be found, and therefore all of the parameters cannot be dealt with. The example I have given you will always work because the correct number of parameters and the appropriate constructors are in the inheritance chain. But modify your main program as follows and see the result. As shown in the following code, I have only supplied two parameters to the constructor instead of three.

main()
{
    Prism test(3,5);
    test.CalcArea();
    test.ShowArea();
    return(0);
}

My compiler simply says:

-------------------Configuration: Listing 5.8b - Win32 Debug-------------------
Compiling...
Listing5.8b.cpp
F:\How To\Chapter 05\Listing5.8b\Listing5.8b.cpp(44) : error C2661:
   ‘Prism::Prism’ : no overloaded function takes 2 parameters
Error executing cl.exe.

Listing5.8b.obj - 1 error(s), 0 warning(s)

Unless you really are experienced in C++ programming this message means very little and it simply scares the beginner.

Now try the following amendment to the main program. This time I have given it four parameters instead of three.

main()
{
    Prism test(3,5,10,4);
    test.CalcArea();
    test.ShowArea();
    return(0);
}

My compiler simply says:

-------------------Configuration: Listing5.8b - Win32 Debug--------------------
Compiling...
Listing5.8b.cpp
F:\How To\Chapter 05\Listing5.8b\Listing5.8b.cpp(44) : error C2661:
    ‘Prism::Prism’ : no overloaded function takes 4 parameters
Error executing cl.exe.

Listing5.8b.obj - 1 error(s), 0 warning(s)

I was using Microsoft Visual C++ version 5 at the time of writing. If you are using a different compiler, the error message and format will be different. The actual error will, of course, be the same.

The error message tells you that the compiler could not find an appropriate constructor, or chain of constructors, to deal with the given number of parameters in the creation of the object.

5.9 Distinguish between virtual classes and nonvirtual classes? How do I know when to use virtual classes and what does the word virtual mean in C++?

Problem

When building up a hierarchical inheritance network, it is difficult to know when and when not to use the word virtual. Often it seems to make no difference whether classes are declared as virtual or not.

Technique

Some simple rules can be applied to verify whether functions should be declared as virtual. It depends upon whether multiple inheritance is to be used. The key is an understanding of the meaning of the term virtual. When a function is declared as virtual, the derived class contains only a reference back to the original base class, and so uses the single occurrence of the original (see Figure 5.23). You can declare any member function as virtual and in most cases there is (to the end user) no apparent difference. However, in order to avoid redefinition of functions in a multiple inheritance model you should always declare functions to be virtual.


Figure 5.23  Two derived classes sharing a virtual base class.

When a function is declared as nonvirtual, the derived class contains a copy of the original base class; therefore, multiple occurrences of the original exist within the inheritance hierarchy (see Figure 5.24).


Figure 5.24  Two derived classes containing copies of the base class.

To demonstrate the art of virtual functions you will build up a sequence of programs that inherit from a simple base class and add ever more functionality to the derived classes. You will use a model based upon Ohm’s Law. Ohm’s Law is the underlying principle of all DC electric circuits and it concerns the relationship between resistance, voltage, and current (see Figure 5.25). Do not be concerned if you aren’t into electronics, it is only the three simple equations that you are interested in.


Figure 5.25  The three Ohm’s Law equations used in this section.

Steps

1.  Start by writing a simple class that holds the value of a resistor (in ohms) and displays the value to the screen. The following code declares the member function Rout to be virtual, but you will find that if you remove the word virtual it makes no difference to the program. The word virtual only has an effect on derived classes of which, as yet, there are none.
// Inheritance

#include <iostream.h>

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

main()
{
    Resistance R1(47000);
    R1.Rout();
    return(0);
}


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.