Coronado Enterprises C++ TUTOR: Chapter 8
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 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 compile and execute this code. This is to make it easy to compile and execute the example programs in this chapter.
INHERIT1.CPP
// Chapter 8 - Program 1
#include <iostream.h>
class vehicle {
protected:
int wheels;
float weight;
public:
void initialize(int in_wheels, float in_weight);
int get_wheels(void) {return wheels;}
float get_weight(void) {return weight;}
float wheel_loading(void) {return weight/wheels;}
};
class car : public vehicle {
int passenger_load;
public:
void initialize(int in_wheels, float in_weight, int people = 4);
int passengers(void) {return passenger_load;}
};
class truck : public vehicle {
int passenger_load;
float payload;
public:
void init_truck(int how_many = 2, float max_load = 24000.0);
float efficiency(void);
int passengers(void) {return passenger_load;}
};
main()
{
vehicle unicycle;
unicycle.initialize(1, 12.5);
cout << "The unicycle has " <<
unicycle.get_wheels() << " wheel.\n";
cout << "The unicycle's wheel loading is " <<
unicycle.wheel_loading() << " pounds on the single tire.\n";
cout << "The unicycle weighs " <<
unicycle.get_weight() << " pounds.\n\n";
car sedan;
sedan.initialize(4, 3500.0, 5);
cout << "The sedan carries " << sedan.passengers() <<
" passengers.\n";
cout << "The sedan weighs " << sedan.get_weight() << " pounds.\n";
cout << "The sedan's wheel loading is " <<
sedan.wheel_loading() << " pounds per tire.\n\n";
truck semi;
semi.initialize(18, 12500.0);
semi.init_truck(1, 33675.0);
cout << "The semi weighs " << semi.get_weight() << " pounds.\n";
cout << "The semi's efficiency is " <<
100.0 * semi.efficiency() << " percent.\n";
}
// initialize to any data desired
void
vehicle::initialize(int in_wheels, float in_weight)
{
wheels = in_wheels;
weight = in_weight;
}
void
car::initialize(int in_wheels, float in_weight, int people)
{
passenger_load = people;
wheels = in_wheels;
weight = in_weight;
}
void
truck::init_truck(int how_many, float max_load)
{
passenger_load = how_many;
payload = max_load;
}
float
truck::efficiency(void)
{
return payload / (payload + weight);
}
// Result of execution
//
// The unicycle has 1 wheel.
// The unicycle's wheel loading is 12.5 pounds on the single tire.
// The unicycle weighs 12.5 pounds.
//
// The sedan carries 5 passengers.
// The sedan weighs 3500 pounds.
// The sedan's wheel loading is 875 pounds per tire.
//
// The semi weighs 12500 pounds.
// The semi's efficiency is 72.929072 percent.
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 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. 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. In this program, the only inheritance is that of variables since the two variables are inherited into 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 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 inherited into 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 106, but since the weight has no way to be initialized, the result is meaningless and lines 66 and 67 are commented out.
As you have surely guessed by now, there is a way around all of these problems and we will cover them shortly. In the meantime, 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.
INHERIT2.CPP
// Chapter 8 - Program 2
#include <iostream.h>
class vehicle {
protected:
int wheels;
float weight;
public:
void initialize(int in_wheels, float in_weight);
int get_wheels(void) {return wheels;}
float get_weight(void) {return weight;}
float wheel_loading(void) {return weight/wheels;}
};
class car : vehicle {
int passenger_load;
public:
void initialize(int in_wheels, float in_weight, int people = 4);
int passengers(void) {return passenger_load;}
};
class truck : vehicle {
int passenger_load;
float payload;
public:
void init_truck(int how_many = 2, float max_load = 24000.0);
float efficiency(void);
int passengers(void) {return passenger_load;}
};
main()
{
vehicle unicycle;
unicycle.initialize(1, 12.5);
cout << "The unicycle has " <<
unicycle.get_wheels() << " wheel.\n";
cout << "The unicycle's wheel loading is " <<
unicycle.wheel_loading() << " pounds on the single tire.\n";
cout << "The unicycle weighs " <<
unicycle.get_weight() << " pounds.\n\n";
car sedan;
sedan.initialize(4, 3500.0, 5);
cout << "The sedan carries " << sedan.passengers() <<
" passengers.\n";
// cout << "The sedan weighs " << sedan.get_weight() << " pounds.\n";
// cout << "The sedan's wheel loading is " <<
// sedan.wheel_loading() << " pounds per tire.\n\n";
truck semi;
// semi.initialize(18, 12500.0);
semi.init_truck(1, 33675.0);
// cout << "The semi weighs " << semi.get_weight() << " pounds.\n";
// cout << "The semi's efficiency is " <<
// 100.0 * semi.efficiency() << " percent.\n";
}
// initialize to any data desired
void
vehicle::initialize(int in_wheels, float in_weight)
{
wheels = in_wheels;
weight = in_weight;
}
void
car::initialize(int in_wheels, float in_weight, int people)
{
passenger_load = people;
wheels = in_wheels;
weight = in_weight;
}
void
truck::init_truck(int how_many, float max_load)
{
passenger_load = how_many;
payload = max_load;
}
float
truck::efficiency(void)
{
return payload / (payload + weight);
}
// Result of execution
//
// The unicycle has 1 wheel.
// The unicycle's wheel loading is 12.5 pounds on the single tire.
// The unicycle weighs 12.5 pounds.
//
// The sedan carries 5 passengers.
INITIALIZING ALL DATA
If you will examine the example program named INHERIT3.CPP, you will find that we have 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.
INHERIT3.CPP
// Chapter 8 - Program 3
#include <iostream.h>
class vehicle {
protected:
int wheels;
float weight;
public:
void initialize(int in_wheels, float in_weight);
int get_wheels(void) {return wheels;}
float get_weight(void) {return weight;}
float wheel_loading(void) {return weight/wheels;}
};
class car : vehicle {
int passenger_load;
public:
void initialize(int in_wheels, float in_weight, int people = 4);
int passengers(void) {return passenger_load;}
};
class truck : vehicle {
int passenger_load;
float payload;
public:
void init_truck(int in_wheels, float in_weight,
int how_many = 2, float max_load = 24000.0);
float efficiency(void);
int passengers(void) {return passenger_load;}
};
main()
{
vehicle unicycle;
unicycle.initialize(1, 12.5);
cout << "The unicycle has " <<
unicycle.get_wheels() << " wheel.\n";
cout << "The unicycle's wheel loading is " <<
unicycle.wheel_loading() << " pounds on the single tire.\n";
cout << "The unicycle weighs " <<
unicycle.get_weight() << " pounds.\n\n";
car sedan;
sedan.initialize(4, 3500.0, 5);
cout << "The sedan carries " << sedan.passengers() <<
" passengers.\n";
// cout << "The sedan weighs " << sedan.get_weight() << " pounds.\n";
// cout << "The sedan's wheel loading is " <<
// sedan.wheel_loading() << " pounds per tire.\n\n";
truck semi;
// semi.initialize(18, 12500.0);
semi.init_truck(1, 33675.0);
// cout << "The semi weighs " << semi.get_weight() << " pounds.\n";
cout << "The semi's efficiency is " <<
100.0 * semi.efficiency() << " percent.\n";
}
// initialize to any data desired
void
vehicle::initialize(int in_wheels, float in_weight)
{
wheels = in_wheels;
weight = in_weight;
}
void
car::initialize(int in_wheels, float in_weight, int people)
{
passenger_load = people;
wheels = in_wheels;
weight = in_weight;
}
void
truck::init_truck(int in_wheels, float in_weight,
int how_many, float max_load)
{
vehicle::initialize(in_wheels, in_weight);
passenger_load = how_many;
payload = max_load;
}
float
truck::efficiency(void)
{
return payload / (payload + weight);
}
// Result of execution
//
// The unicycle has 1 wheel.
// The unicycle's wheel loading is 12.5 pounds on the single tire.
// The unicycle weighs 12.5 pounds.
//
// The sedan carries 5 passengers.
// The semi's efficiency is 41.612484 percent.
WHAT IS PROTECTED DATA?
Examine the program named INHERIT4.CPP for an example we will use to define protected data. 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.
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.
You will notice that the variables named wheels and weight are available to use in the method named initialize() in lines 85 through 91 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.
Be sure to compile and execute this program before continuing on to the next example program.
INHERIT4.CPP
// Chapter 8 - Program 4
#include <iostream.h>
class vehicle {
protected:
int wheels;
float weight;
public:
void initialize(int in_wheels, float in_weight);
int get_wheels(void) {return wheels;}
float get_weight(void) {return weight;}
float wheel_loading(void) {return weight/wheels;}
};
class car : public vehicle {
private:
int passenger_load;
public:
void initialize(int in_wheels, float in_weight, int people = 4);
int passengers(void) {return passenger_load;}
};
class truck : public vehicle {
private:
int passenger_load;
float payload;
public:
void init_truck(int how_many = 2, float max_load = 24000.0);
float efficiency(void);
int passengers(void) {return passenger_load;}
};
main()
{
vehicle unicycle;
unicycle.initialize(1, 12.5);
cout << "The unicycle has " <<
unicycle.get_wheels() << " wheel.\n";
cout << "The unicycle's wheel loading is " <<
unicycle.wheel_loading() << " pounds on the single tire.\n";
cout << "The unicycle weighs " <<
unicycle.get_weight() << " pounds.\n\n";
car sedan;
sedan.initialize(4, 3500.0, 5);
cout << "The sedan carries " << sedan.passengers() <<
" passengers.\n";
cout << "The sedan weighs " << sedan.get_weight() << " pounds.\n";
cout << "The sedan's wheel loading is " <<
sedan.wheel_loading() << " pounds per tire.\n\n";
truck semi;
semi.initialize(18, 12500.0);
semi.init_truck(1, 33675.0);
cout << "The semi weighs " << semi.get_weight() << " pounds.\n";
cout << "The semi's efficiency is " <<
100.0 * semi.efficiency() << " percent.\n";
}
// initialize to any data desired
void
vehicle::initialize(int in_wheels, float in_weight)
{
wheels = in_wheels;
weight = in_weight;
}
void
car::initialize(int in_wheels, float in_weight, int people)
{
passenger_load = people;
wheels = in_wheels;
weight = in_weight;
}
void
truck::init_truck(int how_many, float max_load)
{
passenger_load = how_many;
payload = max_load;
}
float
truck::efficiency(void)
{
return payload / (payload + weight);
}
// Result of execution
//
// The unicycle has 1 wheel.
// The unicycle's wheel loading is 12.5 pounds on the single tire.
// The unicycle weighs 12.5 pounds.
//
// The sedan carries 5 passengers.
// The sedan weighs 3500 pounds.
// The sedan's wheel loading is 875 pounds per tire.
//
// The semi weighs 12500 pounds.
// The semi's efficiency is 72.929072 percent.
WHAT IS PRIVATE DATA?
Examine the file named INHERIT5.CPP where the data is allowed to use the private default. 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.
INHERIT5.CPP
// Chapter 8 - Program 5
#include <iostream.h>
class vehicle {
int wheels;
float weight;
public:
void initialize(int in_wheels, float in_weight);
int get_wheels(void) {return wheels;}
float get_weight(void) {return weight;}
float wheel_loading(void) {return weight/wheels;}
};
class car : public vehicle {
private:
int passenger_load;
public:
void initialize(int in_wheels, float in_weight, int people = 4);
int passengers(void) {return passenger_load;}
};
class truck : public vehicle {
private:
int passenger_load;
float payload;
public:
void init_truck(int how_many = 2, float max_load = 24000.0);
float efficiency(void);
int passengers(void) {return passenger_load;}
};
main()
{
vehicle unicycle;
unicycle.initialize(1, 12.5);
cout << "The unicycle has " <<
unicycle.get_wheels() << " wheel.\n";
cout << "The unicycle's wheel loading is " <<
unicycle.wheel_loading() << " pounds on the single tire.\n";
cout << "The unicycle weighs " <<
unicycle.get_weight() << " pounds.\n\n";
car sedan;
sedan.initialize(4, 3500.0, 5);
cout << "The sedan carries " << sedan.passengers() <<
" passengers.\n";
cout << "The sedan weighs " << sedan.get_weight() << " pounds.\n";
cout << "The sedan's wheel loading is " <<
sedan.wheel_loading() << " pounds per tire.\n\n";
truck semi;
semi.initialize(18, 12500.0);
semi.init_truck(1, 33675.0);
cout << "The semi weighs " << semi.get_weight() << " pounds.\n";
cout << "The semi's efficiency is " <<
100.0 * semi.efficiency() << " percent.\n";
}
// initialize to any data desired
void
vehicle::initialize(int in_wheels, float in_weight)
{
wheels = in_wheels;
weight = in_weight;
}
void
car::initialize(int in_wheels, float in_weight, int people)
{
passenger_load = people;
vehicle::initialize(in_wheels, in_weight);
}
void
truck::init_truck(int how_many, float max_load)
{
passenger_load = how_many;
payload = max_load;
}
float
truck::efficiency(void)
{
return payload / (payload + get_weight());
}
// Result of execution
//
// The unicycle has 1 wheel.
// The unicycle's wheel loading is 12.5 pounds on the single tire.
// The unicycle weighs 12.5 pounds.
//
// The sedan carries 5 passengers.
// The sedan weighs 3500 pounds.
// The sedan's wheel loading is 875 pounds per tire.
//
// The semi weighs 12500 pounds.
// The semi's efficiency is 72.929072 percent.
INHERITING CONSTRUCTORS
Examine the example program named INHERIT6.CPP for yet another variation to our basic program, INHERIT6.CPP 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 one of the constructors is called for a derived class, the 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.
INHERIT6.CPP
// Chapter 8 - Program 6
#include <iostream.h>
class vehicle {
protected:
int wheels;
float weight;
public:
vehicle(void) {wheels = 7; weight = 11111.0;}
void initialize(int in_wheels, float in_weight);
int get_wheels(void) {return wheels;}
float get_weight(void) {return weight;}
float wheel_loading(void) {return weight/wheels;}
};
class car : public vehicle {
int passenger_load;
public:
car(void) {passenger_load = 4;}
void initialize(int in_wheels, float in_weight, int people = 4);
int passengers(void) {return passenger_load;}
};
class truck : public vehicle {
int passenger_load;
float payload;
public:
truck(void) {passenger_load = 3; payload = 22222.0;}
void init_truck(int how_many = 2, float max_load = 24000.0);
float efficiency(void);
int passengers(void) {return passenger_load;}
};
main()
{
vehicle unicycle;
// unicycle.initialize(1, 12.5);
cout << "The unicycle has " <<
unicycle.get_wheels() << " wheel.\n";
cout << "The unicycle's wheel loading is " <<
unicycle.wheel_loading() << " pounds on the single tire.\n";
cout << "The unicycle weighs " <<
unicycle.get_weight() << " pounds.\n\n";
car sedan;
// sedan.initialize(4, 3500.0, 5);
cout << "The sedan carries " << sedan.passengers() <<
" passengers.\n";
cout << "The sedan weighs " << sedan.get_weight() << " pounds.\n";
cout << "The sedan's wheel loading is " <<
sedan.wheel_loading() << " pounds per tire.\n\n";
truck semi;
// semi.initialize(18, 12500.0);
// semi.init_truck(1, 33675.0);
cout << "The semi weighs " << semi.get_weight() << " pounds.\n";
cout << "The semi's efficiency is " <<
100.0 * semi.efficiency() << " percent.\n";
}
// initialize to any data desired
void
vehicle::initialize(int in_wheels, float in_weight)
{
wheels = in_wheels;
weight = in_weight;
}
void
car::initialize(int in_wheels, float in_weight, int people)
{
passenger_load = people;
wheels = in_wheels;
weight = in_weight;
}
void
truck::init_truck(int how_many, float max_load)
{
passenger_load = how_many;
payload = max_load;
}
float
truck::efficiency(void)
{
return payload / (payload + weight);
}
// Result of execution
//
// The unicycle has 7 wheel.
// The unicycle's wheel loading is 1587.285767 pounds on the single tire.
// The unicycle weighs 11111 pounds.
//
// The sedan carries 4 passengers.
// The sedan weighs 11111 pounds.
// The sedan's wheel loading is 1587.285767 pounds per tire.
//
// The semi weighs 11111 pounds.
// The semi's efficiency is 66.666667 percent.
POINTERS TO AN OBJECT AND AN ARRAY OF OBJECTS
Examine the example program named INHERIT7.CPP for examples of the use of an array of objects and a pointer to an object. 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.
INHERIT7.CPP
// Chapter 8 - Program 7
#include <iostream.h>
class vehicle {
protected:
int wheels;
float weight;
public:
void initialize(int in_wheels, float in_weight);
int get_wheels(void) {return wheels;}
float get_weight(void) {return weight;}
float wheel_loading(void) {return weight/wheels;}
};
class car : public vehicle {
int passenger_load;
public:
void initialize(int in_wheels, float in_weight, int people = 4);
int passengers(void) {return passenger_load;}
};
class truck : public vehicle {
int passenger_load;
float payload;
public:
void init_truck(int how_many = 2, float max_load = 24000.0);
float efficiency(void);
int passengers(void) {return passenger_load;}
};
main()
{
vehicle unicycle;
unicycle.initialize(1, 12.5);
cout << "The unicycle has " <<
unicycle.get_wheels() << " wheel.\n";
cout << "The unicycle's wheel loading is " <<
unicycle.wheel_loading() << " pounds on the single tire.\n";
cout << "The unicycle weighs " <<
unicycle.get_weight() << " pounds.\n\n";
car sedan[3];
int index;
for (index = 0 ; index < 3 ; index++) {
sedan[index].initialize(4, 3500.0, 5);
cout << "The sedan carries " << sedan[index].passengers() <<
" passengers.\n";
cout << "The sedan weighs " << sedan[index].get_weight() <<
" pounds.\n";
cout << "The sedan's wheel loading is " <<
sedan[index].wheel_loading() << " pounds per tire.\n\n";
}
truck *semi;
semi = new truck;
semi->initialize(18, 12500.0);
semi->init_truck(1, 33675.0);
cout << "The semi weighs " << semi->get_weight() << " pounds.\n";
cout << "The semi's efficiency is " <<
100.0 * semi->efficiency() << " percent.\n";
delete semi;
}
// initialize to any data desired
void
vehicle::initialize(int in_wheels, float in_weight)
{
wheels = in_wheels;
weight = in_weight;
}
void
car::initialize(int in_wheels, float in_weight, int people)
{
passenger_load = people;
wheels = in_wheels;
weight = in_weight;
}
void
truck::init_truck(int how_many, float max_load)
{
passenger_load = how_many;
payload = max_load;
}
float
truck::efficiency(void)
{
return payload / (payload + weight);
}
// Result of execution
//
// The unicycle has 1 wheel.
// The unicycle's wheel loading is 12.5 pounds on the single tire.
// The unicycle weighs 12.5 pounds.
//
// The sedan carries 5 passengers.
// The sedan weighs 3500 pounds.
// The sedan's wheel loading is 875 pounds per tire.
//
// The sedan carries 5 passengers.
// The sedan weighs 3500 pounds.
// The sedan's wheel loading is 875 pounds per tire.
//
// The sedan carries 5 passengers.
// The sedan weighs 3500 pounds.
// The sedan's wheel loading is 875 pounds per tire.
//
// The semi weighs 12500 pounds.
// The semi's efficiency is 72.929072 percent.
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.
PROGRAMMING EXERCISES
- 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.
- 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.