|
My Training Period: yy hours.
1.4 Using All The Classes
1. // the new main program for inheritance, allvehicle.cpp 2. // compile and run this program 3. 4. #include <iostream> 5. using namespace std; 6. #include "vehicle.h" // the interface of the Cvehicle class 7. #include "car.h" // the interface of the Ccar class 8. #include "truck.h" // the interface of the Ctruck class 9. 10. void main() 11. { 12. Cvehicle unicycle; // the base class 13. 14. cout<<"Unicycle using the Cvehicle base class\n"; 15. cout<<"--------------------------------------\n"; 16. 17. unicycle.initialize(1,12.5); 18. 19. cout<<"Unicycle has "<<unicycle.get_wheels()<<" tire.\n"; 20. cout<<"Unicycle wheel load is "<<unicycle.wheel_load()<<"kg on one 21. tire.\n"; 22. cout<<"Unicycle weight is "<<unicycle.get_weight()<<" kg.\n\n"; 23. 24. Ccar sedan; // the derived class 25. 26. cout<<"Sedan car using the Ccar derived class\n"; 27. cout<<"--------------------------------------\n"; 28. 29. sedan.initialize(4,3500.0,5); 30. 31. cout<<"Sedan car carries "<<sedan.passengers()<<" passengers.\n"; 32. cout<<"Sedan car weight is "<<sedan.get_weight()<<" kg.\n"; 33. cout<<"Sedan car wheel load is "<<sedan.wheel_load()<<"kg per tire.\n\n"; 34. 35. Ctruck trailer; // the derived class 36. 37. cout<<"Trailer using the Ctruck derived class\n"; 38. cout<<"--------------------------------------\n"; 39. 40. trailer.initialize(18,12500.0); 41. trailer.init_truck(1,33675.0); 42. 43. cout<<"Trailer weight is "<<trailer.get_weight()<<" kg.\n"; 44. cout<<"Trailer efficiency is "<<100.00 * trailer.efficiency()<<"%.\n"; 45. 46. // system("pause"); 47. }
47 Lines:Output:
Program 14.8: allvehicle.cpp,the main program |
It uses the base class Cvehicle and also two derived classes to declare objects. This was done to illustrate that all three classes can be used in a single program.
All three of the header files for the classes are included in lines 6 through 8, so the program can use the components of the classes as shown below:
#include "vehicle.h" // the interface of the Cvehicle class
#include "car.h" // the interface of the Ccar class
#include "truck.h" // the interface of the Ctruck class
Notice the implementations of the three classes (vehicle.cpp, car.cpp and truck.cpp) are not in view here and do not need to be in view. We only need these files in compiled form.
This allows the code to be used without access to the source code for the actual implementation of the class. However, it should be clear that the header file definition must be available to act as an interface.
In this program example, only one object of each class is declared and used as an example, but as many as desired could be declared and used in order to accomplish your programming task.
You will notice how clean and uncluttered the source code is for this program. The classes were developed, debugged, and stored away and the interfaces were kept very simple.
Look at the directive in lines 5, 6 and 20 in the vehicle.h file as shown below. These directives have been discussed in Module related to preprocessor directive.
#ifndef VEHICLE_H //preprocessor directive
#define VEHICLE_H
...
...
...
#endif
When we define the derived class Ccar, we are required to supply it with the full definition of the interface to theCvehicle class since Ccar is derived class of Cvehicle and must know all about its base class.
We do that by including the vehicle class (vehicle.h) into theCcar class, and the Ccar class can be compiled. The Cvehicle class must also be included in the header file of the Ctruck class for the same reason.
When we get to the allvehicle.cpp program, we must inform it the details of all three classes, so all three header files must be included as is done in lines 6 through 8 of allvehicle.cpp, but this leads to a problem.
When the preprocessor gets to the Ccar class, it includes theCvehicle class because it is listed in theCcar class header file, but since theCvehicle class already included in line 6 ofallvehicle.cpp, it is included twice and we attempt to re-declare the class Cvehicle.
Of course it is the same declaration, but the compiler simply doesn’t allow re-declaration of a class. We allow the double inclusion of the file (vehicle.h and car.h) and at the same time prevent the double inclusion of the class (Cvehicle) by building a bridge around it using the word VEHICLE_H.
If the word is already defined, the declaration is skipped, but if the word is not defined, the declaration is included and vehicle.h is defined at that time. The end result is the actual inclusion of the class only once, even though the file is included more than once.
Even though ANSI-C allows multiple definitions of entities, provided the definitions are identical, C++ does not permit this. The primary reason is because the compiler would have great difficulty in knowing if it has already made a constructor call for the redefined entity, if any and this also create un optimize codes.
A multiple constructor call for a single object could cause great havoc, so C++ was defined to prevent any multiple constructor calls by making it illegal to redefine any entity.
The nameVEHICLE_H was chosen as the word because it is the name of the file, with the period replaced by the underline. If the name of the file is used systematically in all of your class definitions, you cannot have a name clash because the filename of every class must be unique.
Figure 14.4 and 14.5 has shown that the inheritance concepts will create class hierarchy. From the top, a base class with general description of the object, traversing down of the derived class levels with more details description of the objects.
This class hierarchy provides very powerful ‘tool’ for programming. We can reuse readily available classes which has been developed and tested. At the same time we can combine with our own new defined classes.
This will shorten the program development process and cycle, enhances the software quality and increase the productivity of the programmers.
For example,Microsoft Foundation Classes (MFC) have hundreds readily available classes which arranged in hierarchical manner and you can imagine that there should be thousands of member variables and methods defined, readily available for us to use. The latest is the .NET Framework withmanaged C++, a managed classes.
--------------------------------------------------------------------
Let start with a simple program skeleton.
// inheritance
#include <iostream>
using namespace std;
// a base class
class Base
{
// member variables and member functions...
public:
Base(){}
~Base(){}
protected:
private:
};
// a derived class...
class Derived:public Base
{
// same as normal class actually...
// member variables and member function...
public:
Derived(){}
~Derived(){}
private:
protected:
};
void main()
{
cout<<"Testing the program skeleton..."<<endl;
}
Then, let try the real objects.
// an inheritance
#include <iostream>
using namespace std;
// a class declaration and implementation
// a base class...
class MyFather
{
// member variables and member functions...
private: // the private keyword is optional
char* EyeColor;
char* HairType;
double FamSaving;
protected:
public:
MyFather(){}
~MyFather(){}
char* GetEye()
{ return EyeColor = "Brown";}
char* GetHair()
{ return HairType = "Straight";}
double GetSaving()
{return FamSaving = 30000;}
};
// a derived class...
class MySelf:public MyFather
{
// same as normal class actually...
private:
char* MyEye;
char* MyHair;
public:
MySelf(){}
~MySelf(){}
char* GetMyEye()
{ return MyEye = "Blue";}
char* GetMyHair()
{return MyHair = "Curly";}
protected:
};
// another derived class...
class MySister:public MyFather
{
private: // the private keyword is optional
char* SisEye;
char* SisHair;
public:
MySister(){}
~MySister(){}
char* GetSisEye()
{return SisEye = "Black";}
char* GetSisHair()
{ return SisHair = "Blonde";}
};
// the main program
int main()
{
// base class object...
MyFather Test1;
cout<<"Testing the inheritance program...\n"<<endl;
cout<<"My father's eye is = "<<Test1.GetEye()<<endl;
cout<<"My father's hair is = "<<Test1.GetHair()<<endl;
// derived class object...
MySelf Test2;
cout<<"\nMy eye is = "<<Test2.GetMyEye()<<endl;
cout<<"My hair is = "<<Test2.GetMyHair()<<endl;
// the following are inherited from MyFather class...
cout<<"Our family saving is = $"<<Test2.GetSaving()<<endl;
cout<<"My father's eye is = "<<Test2.GetEye()<<endl;
cout<<"My father's hair is = "<<Test2.GetHair()<<endl;
// another derived class object...
MySister Test3;
cout<<"\nMy sister's eye is = "<<Test3.GetSisEye()<<endl;
cout<<"My sister's hair is = "<<Test3.GetSisHair()<<endl;
// the following are inherited from MyFather class...
cout<<"Our family saving is = $"<<Test3.GetSaving()<<endl;
cout<<"My father's eye is = "<<Test3.GetEye()<<endl;
cout<<"My father's hair is = "<<Test3.GetHair()<<"\n\n";
return 0;
}
If you have noticed, the program examples in this Module become smaller, simpler and manageable compared to what is in the previous Modules.
// inheritance
#include <iostream>
using namespace std;
// class declaration and implementation
// a base class...
class MyFather
{
// member variables and member functions...
private: // the private keyword is optional
char* EyeColor;
char* HairType;
double FamSaving;
protected:
// protected members here…
public:
MyFather(){}
~MyFather(){}
char* GetEye()
{ return EyeColor = "Brown";}
char* GetHair()
{ return HairType = "Straight";}
double GetSaving()
{return FamSaving = 30000;}
};
//derived class...
class MySelf:public MyFather
{
//same as normal class actually...
private:
char* MyEye;
char* MyHair;
public:
MySelf(){}
~MySelf(){}
char* GetMyEye()
{ return MyEye = "Blue";}
char* GetMyHair()
{return MyHair = "Curly";}
protected:
};
//another derived class...
class MySister:public MyFather
{
private:
char* SisEye;
char* SisHair;
public:
MySister(){}
~MySister(){}
char* GetSisEye()
{return SisEye = "Black";}
char* GetSisHair()
{ return SisHair = "Blonde";}
};
// the main program
int main()
{
// base class object...
MyFather Test1;
cout<<"Testing the inheritance program...\n"<<endl;
cout<<"My father's eye is = "<<Test1.GetEye()<<endl;
cout<<"My father's hair is = "<<Test1.GetHair()<<endl;
// derived class object...
MySelf Test2;
cout<<"\nMy eye is = "<<Test2.GetMyEye()<<endl;
cout<<"My hair is = "<<Test2.GetMyHair()<<endl;
// the following are inherited from MyFather class...
cout<<"Our family saving is = $"<<Test2.GetSaving()<<endl;
cout<<"My father's eye is = "<<Test2.GetEye()<<endl;
cout<<"My father's hair is = "<<Test2.GetHair()<<endl;
// another derived class object...
MySister Test3;
cout<<"\nMy sister's eye is = "<<Test3.GetSisEye()<<endl;
cout<<"My sister's hair is = "<<Test3.GetSisHair()<<endl;
// the following are inherited from MyFather class...
cout<<"Our family saving is = $"<<Test3.GetSaving()<<endl;
cout<<"My father's eye is = "<<Test3.GetEye()<<endl;
cout<<"My father's hair is = "<<Test3.GetHair()<<"\n\n";
return 0;
}
-------------------------------------------------------------------------------
The following is a previous example compiled usingg++. To link more than one object files, it is better to create makefile.
// **************herit2.cpp**************
// **************FEDORA 3, g++ x.x.x****
#include <iostream>
using namespace std;
// a class declaration and implementation
// base class...
class MyFather
{
// member variables and member functions...
private: // the private keyword is optional
char* EyeColor;
char* HairType;
double FamSaving;
protected:
public:
MyFather(){}
~MyFather(){}
char* GetEye()
{return EyeColor = "Brown";}
char* GetHair()
{return HairType = "Straight";}
double GetSaving()
{return FamSaving = 30000;}
};
// derived class...
class MySelf:public MyFather
{
// same as normal class actually...
private:
char* MyEye;
char* MyHair;
public:
MySelf(){}
~MySelf(){}
char* GetMyEye()
{return MyEye = "Blue";}
char* GetMyHair()
{return MyHair = "Curly";}
protected:
//...
};
// another derived class...
class MySister:public MyFather
{
private:
char* SisEye;
char* SisHair;
public:
MySister(){}
~MySister(){}
char* GetSisEye()
{return SisEye = "Black";}
char* GetSisHair()
{return SisHair = "Blonde";}
};
// the main program
int main()
{
// base class object...
MyFather Test1;
cout<<"Testing the inheritance program...\n"<<endl;
cout<<"My father's eye is = "<<Test1.GetEye()<<endl;
cout<<"My father's hair is = "<<Test1.GetHair()<<endl;
// derived class object...
MySelf Test2;
cout<<"\nMy eye is = "<<Test2.GetMyEye()<<endl;
cout<<"My hair is = "<<Test2.GetMyHair()<<endl;
// the following are inherited from MyFather class...
cout<<"Our family saving is = $"<<Test2.GetSaving()<<endl;
cout<<"My father's eye is = "<<Test2.GetEye()<<endl;
cout<<"My father's hair is = "<<Test2.GetHair()<<endl;
// another derived class object...
MySister Test3;
cout<<"\nMy sister's eye is = "<<Test3.GetSisEye()<<endl;
cout<<"My sister's hair is = "<<Test3.GetSisHair()<<endl;
// the following are inherited from MyFather class...
cout<<"Our family saving is = $"<<Test3.GetSaving()<<endl;
cout<<"My father's eye is = "<<Test3.GetEye()<<endl;
cout<<"My father's hair is = "<<Test3.GetHair()<<"\n\n";
return 0;
}
[bodo@bakawali ~]$ g++ herit2.cpp -o herit2
[bodo@bakawali ~]$ ./herit2
Testing the inheritance program...
My father's eye is = Brown
My father's hair is = Straight
My eye is = Blue
My hair is = Curly
Our family saving is = $30000
My father's eye is = Brown
My father's hair is = Straight
My sister's eye is = Black
My sister's hair is = Blonde
Our family saving is = $30000
My father's eye is = Brown
My father's hair is = Straight
tenouk C++ object inheritance program examples