/* In the hardware store example, we examined the class relationships, and the difference between variability in behaviour and value. In that example, not all the inheritance relationships was verified. In the following example inheritance relationships are "natural", and public inheritance is appropriate. However, the decision to use public inheritance raises other questions with respect to the detailed distribution of the and function members of the classes in the inheritance hierarchy. C++ Style Example 2 Vehicles and garages The program manipulates vehicles, recording their entry and exit from a parking garage. Classes Car and Truck are derived from a common base class, Vehicle. The inheritance hierarchy is shown here: Vehicle / \ / \ Car Truck Vehicles identify themselves by printing a message with the vehicle's type (car or truck) and license plate number. The main function exercises the Garage class by inserting and removing Truck and Car objects from a Garage called Park. The public interface to class Garage is defined in terms of pointers to Vehicle objects. Note that Garage is more than just a bounded collection of pointers to Vehicle. Each vehicle registered in the garage has an associated bay number, the only key by which it may be referred to within the Garage. Questions: - Which members should be public, private or protected? - Which functions should be virtual? - There is a serious bug in the interaction between the base class and the derived class. Find it and fix it. Read the program, and make suggestions to create better coupling between classes. */ #include <stdio.h> #include <string.h> class Vehicle { public: Vehicle() { plate = 0; } Vehicle(char *p) { plate = new char[strlen(p)+1]; strcpy(plate, p); } ~Vehicle() { delete [] plate; } virtual void identify() { printf("generic vehicle\n"); } protected: char *plate; }; class Car : public Vehicle { public: Car() : Vehicle() { } Car(char *p) : Vehicle(p) { }; void identify() { printf("car with plate %s\n", plate); } }; class Truck : public Vehicle { public: Truck() : Vehicle() { } Truck(char *p) : Vehicle(p) { }; void identify() { printf("truck with plate %s\n", plate); } }; class Garage { public: Garage(int max); ~Garage(); int accept(Vehicle*); Vehicle *release(int bay); void listVehicles(); private: int maxVehicles; Vehicle **parked; }; Garage::Garage(int max) { maxVehicles = max; parked = new Vehicle*[maxVehicles]; for( int bay = 0; bay < maxVehicles; ++bay ) { parked[bay] = 0; } } Garage::~Garage() { delete [] parked; } int Garage::accept(Vehicle *veh) { for( int bay = 0; bay < maxVehicles; ++bay ) if( !parked[bay] ) { parked[bay] = veh; return( bay ); } return( -1 ); // No free bay } Vehicle *Garage::release(int bay) { if( bay < 0 || bay > maxVehicles ) return 0; Vehicle *veh = parked[bay]; parked[bay] = 0; return( veh ); } void Garage::listVehicles() { for( int bay = 0; bay < maxVehicles; ++bay ) if( parked[bay] ) { printf("Vehicle in bay %d is: ", bay); parked[bay]->identify(); } } Car c1("AAA100"); Car c2("BBB200"); Car c3("CCC300"); Truck t1("TTT999"); Truck t2("SSS888"); Truck t3("UUU777"); int main( ) { Garage Park(14); Park.accept(&c1); int t2bay = Park.accept(&t2); Park.accept(&c3); Park.accept(&t2); Park.release(t2bay); Park.listVehicles(); return 0; } /* The output of the program is the following: Vehicle in bay 0 is: car with plate AAA100 Vehicle in bay 2 is: car with plate CCC300 Vehicle in bay 3 is: truck with plate SSS888 */