The source code for this tutorial is available in C++ Inheritance source codes.
The C++ programming abilities that supposed to be acquired: Able to understand and use:
|
| 15.1 An Introduction
1. // program inherit1.cpp 2. #include <iostream> 3. using namespace std; 4. 5. // class declaration part 6. class vehicle 7. { 8. // protected keyword: these variables will be automatically 9. // inherited by all the derived class but not outside the 10. // base and derived class of vehicle 11. protected: 12. int wheels; 13. double weight; 14. public: 15. void initialize(int input_wheels, double input_weight); 16. int get_wheels(void) {return wheels;} 17. double get_weight(void) {return weight;} 18. double wheel_load(void) {return (weight/wheels);} 19. }; 20. 21. // derived class declaration part 22. class car : public vehicle 23. { 24. int passenger_load; 25. public: 26. void initialize(int input_wheels, double input_weight, int people = 4); 27. int passengers(void) 28. { 29. return passenger_load; 30. } 31. }; 32. 33. class truck : public vehicle 34. { 35. int passenger_load; 36. double payload; 37. public: 38. void init_truck(int how_many = 4, double max_load = 24000.0); 39. double efficiency(void); 40. int passengers(void) {return passenger_load;} 41. }; 42. 43. // the main program 44. int main() 45. { 46. vehicle unicycle; 47. unicycle.initialize(1, 12.5); 48. 49. cout<<"Using base class, vehicle\n"; 50. cout<<"-------------------------\n"; 51. cout<<"The unicycle has " <<unicycle.get_wheels()<<" wheel.\n"; 52. cout<<"The unicycle's wheel loading is "<<unicycle.wheel_load()<<" kg on the 53. single tire.\n"; 54. cout<<"The unicycle weighs "<<unicycle.get_weight()<<" kg.\n\n"; 55. 56. car sedan_car; 57. sedan_car.initialize(4, 3500.0, 5); 58. 59. cout<<"Using derived class, car\n"; 60. cout<<"------------------------\n"; 61. cout<<"The sedan car carries "<<sedan_car.passengers()<<" passengers.\n"; 62. cout<<"The sedan car weighs "<<sedan_car.get_weight()<<" kg.\n"; 63. cout<<"The sedan's car wheel loading is "<<sedan_car.wheel_load()<<" kg per 64. tire.\n\n"; 65. truck trailer; 66. trailer.initialize(18, 12500.0); 67. trailer.init_truck(1, 33675.0); 68. 69. cout<<"Using derived class, truck\n"; 70. cout<<"--------------------------\n"; 71. cout<<"The trailer weighs "<< trailer.get_weight()<< " kg.\n"; 72. cout<<"The trailer's efficiency is "<<100.0 * trailer.efficiency()<<" %.\n"; 73. 74. // system("pause"); 75. return 0; 76. } 77. 78. // base and derived class implementation part 79. // initialize to any data desired, own by base class 80. void vehicle::initialize(int input_wheels, double input_weight) 81. { 82. wheels = input_wheels; 83. weight = input_weight; 84. } 85. 86. // initialize() method own by derived car class 87. void car::initialize(int input_wheels, double input_weight, int people) 88. { 89. // class base variables used by derived car class, 90. // because of the protected keyword 91. passenger_load = people; 92. wheels = input_wheels; 93. weight = input_weight; 94. } 95. 96. void truck::init_truck(int how_many, double max_load) 97. { 98. passenger_load = how_many; 99. payload = max_load; 100. } 102. 103. double truck::efficiency(void) 104. { 105. return payload / (payload + weight); 106. }
|
-----------------------------------------------------------------------------------------------------------------------------

The difference is that some of the simpler methods in the classes have been changed to inline code.
In a practical programming situation, shorter and simple methods should be programmed inline since the actual code just to return a simple value is shorter than the code required to send a message to a non-inline method.
Other change is the reordering of the classes and related methods with the classes all defined first, followed by the main program.
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.
This arrangement violates the C++ rules and the use of the separate compilation, but is only done here for convenience.
The best way is to package all the program examples in this Module as the class packaging explained in C++ Data Encapsulation.
As mentioned before, the two derived classes, car and truck, each one has a similar variable named passenger_load which is legal because they are defined in different classes.
The car class has a method of the same name, initialize(), as one declared in the base class named vehicle.
Notice that the method initialize() is declared in the derived car class, so, it hides the method of the same name which is part of the base class, and there may be other time which 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:
void vehicle::initialize(int input_wheels, double input_weight)
The number and types of parameters must agree with those of the method in the base class.
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 base class into a derived class and have free access to all data in the base class.
This would completely override the protection achieved by using the information hiding. For this reason, the data in a class should 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 derived classes and have them act just as though they were declared as a part of those classes also. For this reason, C++ has provided the keyword protected.
In this program example, the keyword protected is given in line 11 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 base class or derived classes.
...
protected:
int wheels;
double weight;
...
As mentioned before, all data are automatically defaulted to private at the beginning of a class if no specifier is given.
You will notice that the variables named wheels and weight are available for use in the method named initialize() in lines 87 through 94 as shown below, just as if they were declared as a part of the car class itself.
void car::initialize(int input_wheels, double input_weight, int people)
{
// class base variables used by derived car class,
// because of the protected keyword
passenger_load = people;
wheels = input_wheels;
weight = input_weight;
}
They are available because they were declared protected in the base class. They would be available here if they had been declared public in the base class, but then they would be available outside of both classes and we would lose our protection.
We can now conclude the rules for the three means of defining variables and methods specifiers through the private, protected and public keywords.
| Specifier | Description |
| private | The variables and methods are not available to any outside calling routines, and they also are not available to any derived classes inheriting this class. Class members are private by default. You can override the default struct access with private or protected but you cannot override the default union access. friend declarations are not affected by this access specifier. |
| 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. You can override the default struct access with private or protected but you cannot override the default union access. friend declarations are not affected by this access specifier. |
| public | All variables and methods are freely available to all outside calling routines and to all derived classes. Members of a struct or union are public by default. You can override the default struct access with private or protected but you cannot override the default union access. friend declarations are not affected by this access specifier. |
|
Table 15.1: Member variable and method specifier | |
15.4 The Private Data And Inheritance
|
|
1. // program inherit2.cpp 2. #include <iostream>
3. using namespace std; 4. 5. // a base and derived class declaration part
6. class vehicle
7. {
8. // protected:
9. // note this is removed, so it is private now
10. int wheels;
11. double weight;
12. public: // a public specifier
13. void initialize(int input_wheels, double input_weight);
14. int get_wheels(void) {return wheels;}
15. double get_weight(void) {return weight;}
16. double wheel_load(void) {return (weight/wheels);}
17. };
18.
19. class car : public vehicle
20. {
21. int passenger_load;
22. public:
23. void initialize(int input_wheels, double input_weight, int people = 4);
24. int passengers(void) {return passenger_load;}
25. };
26. 27. class truck : public vehicle
28. {
29. int passenger_load;
30. double payload;
31. public:
32. void init_truck(int how_many = 4, double max_load = 24000.0);
33. double efficiency(void);
34. int passengers(void) {return passenger_load;}
35. };
36. 37. // the main program
38. int main()
39. {
40. vehicle unicycle;
41. unicycle.initialize(1, 12.5);
42.
43. cout<<"Using base class, vehicle\n";
44. cout<<"-------------------------\n";
45. cout<<"The unicycle has "<<unicycle.get_wheels()<<" wheel.\n";
46. cout<<"The unicycle's wheel load is "<<unicycle.wheel_load()<<" kg
47. on the single tire.\n";
48. cout<<"The unicycle weighs "<<unicycle.get_weight()<<" kg.\n\n";
49.
50. car sedan_car;
51. sedan_car.initialize(4, 3500.0, 5);
52.
53. cout<<"Using derived class, car\n";
54. cout<<"------------------------\n";
55. cout<<"The sedan car carries "<<sedan_car.passengers()<<" passengers.\n";
56. cout<<"The sedan car weighs "<<sedan_car.get_weight()<< " kg.\n";
57. cout<<"The sedan car's wheel loading is "<<sedan_car.wheel_load()<<
58. " kg per tire.\n\n";
59.
60. truck trailer;
61. trailer.initialize(18, 12500.0);
62. trailer.init_truck(1, 33675.0);
63.
64. cout<<"Using derived class, truck\n";
65. cout<<"--------------------------\n";
66. cout<<"The trailer weighs "<<trailer.get_weight()<<" kg.\n";
67. cout<<"The trailer's efficiency is "<<100.0 * trailer.efficiency()<<" %.\n";
68.
69. // system("pause");
70. return 0;
71. }
72. 73. // base and derived class implementation part
74. // initialize to any data desired, this method own by base class 75. void vehicle::initialize(int input_wheels, double input_weight)
76. {
77. wheels = input_wheels;
78. weight = input_weight;
79. }
80.
81. // this method own by derived class
82. void car::initialize(int input_wheels, double input_weight, int people)
83. {
84. passenger_load = people;
85.
86. // this variable are invalid anymore because both wheels
87. // and weight are private now.
88. // wheels = input_wheels;
89. // weight = input_weight;
90. vehicle::initialize(input_wheels, input_weight);
91. // added statement, using base class method instead of derived class
92. }
93.
94. void truck::init_truck(int how_many, double max_load)
95. {
96. passenger_load = how_many;
97. payload = max_load;
98. }
99. 100. double truck::efficiency(void)
101. {
102. // changed from program inherit1.cpp, from weight to get_weight()
103. return payload / (payload + get_weight());
104. }

In this program, the data is not available directly for use in the derived classes, so the only way the data (member variables) in the base class can be used is by sending messages to methods in the base class, within the derived class.
You should think about how the class you define will be used. If you think somebody should 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 derived class.
Lines 88 and 89 are invalid now since the members are not visible, so they are commented out as shown below:
// wheels = input_wheels;
// weight = input_weight; But line 90 now does the job they did before they were hidden by calling the public method of the base class as shown below:
vehicle::initialize(input_wheels, input_weight); // added statement, using base class method instead of derived class You will notice that the data is still available in lines 77 and 78 as shown below, just as they were before because the member variables are protected in the vehicle class. Compile and run this program.
wheels = input_wheels; weight = input_weight;
tenouk C++ inheritance programming object oriented tutorial