


                                                        Chapter 8
                                                 MORE INHERITANCE

In the last chapter we developed a model using modes of 
transportation to illustrate the concept of inheritance.  In this 
chapter we will use that model to illustrate some of the finer 
points of inheritance and what it can be used for.  If it has 
been a while since you read and studied chapter 7, it would be 
good for you to return to that material and review it in 
preparation for a more detailed study of the topic of 
inheritance.


REORGANIZED FILE STRUCTURE
-----------------------------------------------------------------
A close examination of the file named          ==================
INHERIT1.CPP will reveal that it is identical     INHERIT1.CPP
to the program developed in chapter 7 named    ==================
ALLVEHIC.CPP except that the program text is 
rearranged.  The biggest difference is that some of the simpler 
methods in the classes have been changed to inline code to 
shorten the file considerably.  In a practical programming 
situation, methods that are this short should be programmed 
inline since the actual code to return a simple value is shorter 
than the code required to send a message to a non-inline method.

The only other change is the reordering of the classes and 
associated methods with the classes all defined first, followed 
by the main program.  This puts all class interface definitions 
on a single page to make the code easier to study.  The 
implementations for the methods are deferred until the end of 
the file where they are available for quick reference but are not 
cluttering up the class definitions which we wish to study 
carefully in this chapter.  This should be an indication to you 
that there is considerable flexibility in the way the classes and 
methods can be arranged in C++.  Of course you realize that this 
violates the spirit of C++ and its use of separate compilation, 
but is only done here for convenience.  The best way to package 
all of the example programs in this chapter is like the packaging 
illustrated in chapter 7.

As mentioned before, the two derived classes, car and truck, each 
have a variable named passenger_load which is perfectly legal, 
and the car class has a method of the same name, initialize(), as 
one defined in the super-class named vehicle.  The rearrangement 
of the files in no way voids this allowable repeating of names.

After you have convinced yourself that this program is truly 
identical to the program named ALLVEHIC.CPP from chapter 7, 
compile and execute it with your compiler to assure yourself that 
this arrangement is legal.  Due to this means of code packaging, 
you will not need a "make" file or a "project" capability to 

                                                         Page 8-1

                                     Chapter 8 - More Inheritance

compile and execute this code.  This is to make it easy to 
compile and execute the example programs in this chapter.


THE SCOPE OPERATOR
-----------------------------------------------------------------
Because the method initialize() is defined in the derived car 
class, it hides the method of the same name which is part of the 
base class, and there may be times you wish to send a message to 
the method in the base class for use in the derived class object.  
This can be done by using the scope operator in the following 
manner in the main program;

   sedan.vehicle::initialize(4, 3500.0);

As you might guess, the number and types of parameters must agree 
with those of the method in the base class because it will 
respond to the message.


HIDDEN METHODS
-----------------------------------------------------------------
Examine the file named INHERIT2.CPP carefully  ==================
and you will notice that it is a repeat of        INHERIT2.CPP
the last example program with a few minor      ==================
changes.

You will notice that the derived classes named car and truck do 
not have the keyword public prior to the name of the base class 
in the first line of each.  The keyword public, when included 
prior to the base class name, makes all of the methods defined in 
the base class available for use in the derived class just as if 
they were defined as part of the derived class.  Therefore, in 
the previous program, we were permitted to call the methods 
defined as part of the base class from the main program even 
though we were working with an object of one of the derived 
classes.  In this program, the methods are inherited as private 
and are therefore unavailable to any code outside of this class.  
One example of when we did this, was when we sent a message to 
the sedan to get its weight in an output statement of the main 
program.

In the present program, without the keyword public prior to the 
base class name, the only methods available for objects of the 
car class, are those that are defined as part of the class 
itself, and therefore we only have the methods named initialize() 
and passengers() available for use with objects of class car.

When we declare an object of type car, according to the 
definition of the C++ language, it contains three variables.  It 
contains the one defined as part of its class named 
passenger_load and the two that are part of its parent class, 
wheels and weight.  All are available for direct use within its 

                                                         Page 8-2

                                     Chapter 8 - More Inheritance

methods because of the use of the keyword protected in the base 
class.  The variables are a part of an object of class car when 
it is declared and are stored as part of the object.  We will 
show you the details of access to the parent class variables 
within derived classes shortly in this chapter.  For now, we will 
return to the use of the subclasses in this example program.

The observant student will notice that several of the output 
statements have been commented out of the main program since they 
are no longer legal or meaningful operations.  Lines 57 through 
59 have been commented out because the methods named get_weight() 
and wheel_loading() are not available as members of the car class 
without the keyword public in the car class definition.  You will 
notice that initialize() is still available but this is the one 
in the car class, not the method of the same name in the vehicle 
class.

Moving on to the use of the truck class in the main program, we 
find that lines 63 and 65 are commented out for the same reason 
as given above, but lines 66 and 67 are commented out for an 
entirely different reason.  Even though the method named 
efficiency() is available and can be called as a part of the 
truck class, it cannot be used because we have no way to 
initialize the wheels or weight of the truck objects.  We can get 
the weight of the truck objects, as we have done in line 108, but 
since the weight has no way to be initialized, the result is 
meaningless and lines 66 and 67 are commented out.

Be sure to compile and execute this example program to see that 
your compiler gives the same result.  It would be a good exercise 
for you to reintroduce some of the commented out lines to see 
what sort of an error message your compiler issues for these 
errors.


INITIALIZING ALL DATA
-----------------------------------------------------------------
If you will examine the example program named  ==================
INHERIT3.CPP, you will find that we have          INHERIT3.CPP
fixed the initialization problem that we left  ==================
dangling in the last example program.

The method named init_truck() now contains all four of the 
parameters as input data which get transferred to the four 
variables.  Following the initialization, it is permissible to 
call the semi.efficiency() method in line 67 and 68 of the main 
program.  Be sure to compile and execute this program following 
your detailed study of it.






                                                         Page 8-3

                                     Chapter 8 - More Inheritance

WHAT IS PROTECTED DATA?
-----------------------------------------------------------------
Examine the program named INHERIT4.CPP for an  ==================
example we will use to define protected data.     INHERIT4.CPP
Just to make the program more versatile, we    ==================
have returned to the use of the keyword public 
prior to the name of the parent classes in lines 18 and 29 of the 
class definitions which results in public inheritance.

If the data within a base class were totally available in all 
classes inheriting that base class, it would be a simple matter 
for a programmer to inherit the superclass into a derived class 
and have free access to all data in the parent class.  This would 
completely override the protection afforded by the use of 
information hiding.  For this reason, the data in a class are 
not automatically available to the methods of an inheriting 
class.  There are times when you may wish to automatically 
inherit all variables directly into the subclasses and have them 
act just as though they were defined as a part of those classes 
also.  For this reason, the designer of C++ has provided the 
keyword protected.

In the present example program, the keyword protected is given in 
line 5 so that all of the data of the vehicle class can be 
directly imported into any derived classes but are not available 
outside of the class or derived classes.  All data are 
automatically defaulted to private type if no specifier is given.  
The keyword private can be used as illustrated in lines 19 and 30 
but adds nothing due to the fact that class members default to 
private by definition at the beginning of a class.

You will notice that the variables named wheels and weight are 
available to use in the method named initialize() in lines 86 
through 92 just as if they were declared as a part of the car 
class itself.  We can now state the rules for the three means of 
defining variables and methods.

    private - The variables and methods are not available to 
        any outside calling routines, and they are not available 
        to any derived classes inheriting this class.

    protected - The variables and methods are not available 
        to any outside calling routines, but they are directly 
        available to any derived class inheriting this class.

    public - All variables and methods are freely available 
        to all outside calling routines and to all derived 
        classes.

You will note that these three means of definition can also be 
used in a struct type.  The only difference with a struct is that 
everything defaults to public until one of the other keywords is 
used.

                                                         Page 8-4

                                     Chapter 8 - More Inheritance

Be sure to compile and execute this program before continuing on 
to the next example program.


WHAT IS PRIVATE DATA?
-----------------------------------------------------------------
Examine the file named INHERIT5.CPP where the  ==================
data is allowed to use the private default.       INHERIT5.CPP
In this program, the data is not available     ==================
for use in the derived classes, so the only 
way the data in the base class can be used is through use of 
messages to methods in the base class.

It seems a little silly to have to call methods in the base class 
to get to the data which is actually a part of the derived class, 
but that is the way C++ is defined to work.  This would indicate 
to you that you should spend some time thinking about how any 
class you define will be used.  If you think somebody may wish to 
inherit your class into a new class and expand it, you should 
make the data members protected so they can be easily used in the 
new class.  Be sure to compile and execute this program.


INHERITING CONSTRUCTORS
-----------------------------------------------------------------
Examine the example program named INHERIT6.CPP   ================
for yet another variation to our basic             INHERIT6.CPP
program, this time adding constructors.  The     ================
vehicle class has a constructor to initialize 
the number of wheels and the weight to the indicated values and 
has no surprising constructs.  The car and truck classes each 
have a constructor also to initialize their unique variables to 
some unique values.  If you jump ahead to the main program, you 
will find that the initializing statements are commented out for 
each of the objects so we must depend on the constructors to 
initialize the variables.  The most important thing to glean from 
this example program is the fact that when a constructor is 
called for a derived class, a constructor is also called for the 
parent class.  In fact, the constructor for the parent class will 
be called before the constructor for the derived class is called.  
All of the data will be initialized, including the data inherited 
from the parent class.

We will say much more about constructors used with inheritance in 
the next chapter of this tutorial.  Be sure to compile and 
execute this example program.


POINTERS TO AN OBJECT AND AN ARRAY OF OBJECTS
-----------------------------------------------------------------
Examine the example program named              ==================
INHERIT7.CPP for examples of the use of an        INHERIT7.CPP
array of objects and a pointer to an object.   ==================

                                                         Page 8-5

                                     Chapter 8 - More Inheritance

In this program, the objects are instantiated 
from an inherited class and the intent of this program is to 
illustrate that there is nothing magic about a derived class.

The program is identical to the first program in this chapter 
until we get to the main program where we find an array of 3 
objects of class car declared in line 52.  It should be obvious 
that any operation that is legal for a simple object is legal for 
an object that is part of an array, but we must be sure to tell 
the system which object of the array we are interested in by 
adding the array subscript as we do in lines 56 through 62.  The 
operation of this portion of the program should be very easy for 
you to follow, so we will go on to the next construct of 
interest.

You will notice, in line 65, that we do not declare an object of 
type truck but a pointer to an object of type truck.  In order to 
use the pointer, we must give it something to point at which we 
do in line 67 by dynamically allocating an object.  Once the 
pointer has an object to point to, we can use the object in the 
same way we would use any object, but we must use the pointer 
notation to access any of the methods of the object.  This is 
illustrated for you in lines 68 through 72, and will be further 
illustrated in the example program of chapter 12 in this 
tutorial.

Finally, we deallocate the object in line 73.  You should spend 
enough time with this program to thoroughly understand the new 
material presented here, then compile and execute it.


THE NEW TIME CLASS
-----------------------------------------------------------------
We began a series of nontrivial classes in chapter 5 where we 
developed a date class, then a time class, and finally a newdate 
class in the last chapter.  Now it is your turn to add to this 
series.  Your assignment is to develop the newtime class which 
inherits the time class and adds a new member variable named 
seconds_today and a method to calculate the value of seconds 
since midnight to fill the variable.

A complete solution to this problem will be found in the ANSWERS 
directory on the distribution disk.  The files named NEWTIME.H, 
NEWTIME.CPP, and TRYNTIME.CPP are the solution files.  It would 
be a good exercise for you to attempt to write this new class 
before you look at the example solution.








                                                         Page 8-6

                                     Chapter 8 - More Inheritance

PROGRAMMING EXERCISE
-----------------------------------------------------------------
1.  Remove the comment delimiters from lines 65 through 67 of 
    INHERIT2.CPP to see what kind of results are returned.  
    Remove them from line 57 to see what kind of an error is 
    reported by the compiler for this error.2.   Add cout 
    statements to each of the constructors of INHERIT5.CPP to 
    output messages to the monitor so you can see the order of 
    sending messages to the constructors.













































                                                         Page 8-7
