CIS 22B
Assignment E
Use the style guide, including Additonal styles beginning with Assignment D.
In Problem E1 we use an array of pointers to Car and make a copy of the users Car objects in the heap.
In Problem E2 we will use inheritance to provide specizations of the Car class in the child classes FreightCar and PassengerCar.
Then in Problem E3 we will put this all together with a StringOfCars class that can contain Car, FreightCar, or PassengerCar objects, or a mix of these three.
Problem E1
Copy the solution from problem D2 and make the name E1.
Keep the same order for the functions as in problem D2.
-
Car constructors and destructor within the Car class definition
- default constructor
- copy constructor
- other constructors
- destructor
-
StringOfCars constructors and destructor within the StringOfCar class definition
- default constructor
- copy constructor
- other constructors
- destructor
- main
-
Car member functions declared within the Car class but defined later
- setup
- output
- operator=
-
StringOfCars member functions declared within the StringOfCars class but defined later
- output
- push
- pop
- global functions
- operator== with Car parameters
- input
In the StringOfCars class, Change the array of Car objects to an array of pointers to Car objects.
To do this you need to change the pointer type from Car * to Car **
Then we will need to make changes to use these pointers.
The constructors, destructor, and member functions will have similar operation, but will need changes to work with pointers.
I suggest you make the following changes, one at a time.
- All the StringOfCars constructors will get space for Car * elements, rather than Car elements in the array. To allow this the pointer in the private data for the StringOfCars class will be: Car ** ptr;
- All the StringOfCars constructors will set each unused element in the array to zero. This might best be done by setting them all to zero before using the array.
- The output function needs to dereference the pointers to get at the Car objects.
- Change the push function. It will take a parameter that is a Car by constant reference. It will allocate space in the heap for one Car object that is a copy of the Car parameter and then put the pointer to that Car in the array. Then it will increment the carCount.
- The copy constructor will get space for the array of Car* elements and set them to zero. It will set the carCount to zero. Then it will use the push function to push each each Car object into the array.
- The pop function will take a Car parameter by reference. It will copy the Car to the reference parameter. Then it will delete the Car from the heap. It will set the entry in the array that is no longer used to 0. It will decrement the carCount.
- The distructor will need to delete each Car pointed to by the array, and then delete the array.
Test with the same tests as in Problem D2.
Problem E2
Copy the solution from problem E1 and make the name E2.
Order of functions in the code:
Note that the setKind member functions have been added.
Note that the FreigntCar and PassengerCar classes have been added with their member functions.
-
Car constructors and destructor within the Car class definition
- default constructor
- copy constructor
- other constructors
- destructor
-
FreightCar constructors and destructor within the FreightCar class definition
- default constructor
- copy constructor
- other constructors
- destructor
-
PassengerCar constructors and destructor within the PassengerCar class definition
- default constructor
- copy constructor
- other constructors
- destructor
-
StringOfCars constructors and destructor within the StringOfCar class definition
- default constructor
- copy constructor
- other constructors
- destructor
- main
-
Car member functions declared within the Car class but defined later
- setup
- output
- operator=
- setKind
-
FreightCar member functions declared within the FreightCar class but defined later
- operator=
- setKind
-
PassengerCar member functions declared within the PassengerCar class but defined later
- operator=
- setKind
- operator== friend of Car
-
StringOfCars member functions declared within the StringOfCars class but defined later
- output
- push
- pop
- input
In this problem we will use inheritance to create two new classes, both of which will inherit from the class Car
Do not change the StringOfCar class .
We are not using a StringOfCars in this problem, but will need it later.
The kind of cars for the three classes will be:
Car: business, maintenance, other
FreightCar: box, tank, flat, otherFreight
PassengerCar: chair, sleeper, otherPassenger
Change private to protected in the Car class only.
Make two classes that inherit from the Car class: FreightCar and PassengerCar.
No additional member data will be added.
Each class will need a default constructor, a copy constructor, and a constructor that has five parameters.
Create a function named setKind that is a member function of the class Car.
It takes the string containing the kind as a parameter.
It sets the kind field to business
if the parameter is business
.
It sets the kind firld to maintenance
if the parameter is maintenance
.
Otherwise it sets the kind field to other
.
Create setKind functions for the FreightCar and PassengerCar classes that are similar to the setKind function for the Car class,
but with different values.
The setKind function for the FreightCar class uses only the values:
box
, tank
, flat
, otherFreight
The setKind function for the PassengerCar class uses only the values:
chair
, sleeper
, otherPassenger
Make the setKind and destructor functions virtual in the Car class only.
This is only done in the declaration, not the definition of the functions.
This is only done in the parent class, not the children classes.
Change the setup function to call the setKind function using the following line of code.
(*this).setKind(kindParm)
where kindParm is the kind parameter in the setup function.
This uses the current car because *this is the current car.
The current car could be a Car object, a FrightCar object, or a PassengerCar object
because all three classes use the setup function, which is in the parent Car class.
Remove all the code from the main function and replace it with the following.
Create a Car object named car1 with the following data:
SLSF 46871 wrecker true Memphis
Print the car.
Create a Freight Car object named car2 with the following data:
MP 98765 gondola true Saint Louis
Print the freignt car.
Create a Passenger Car object named car3 with the following data:
PAPX 145 combine true Tucson
Print the passenger car.
Problem E3
Copy the solution from problem E2 and make the name E3.
Order of functions in the code:
Note that two additional push functions have been added.
-
Car constructors and destructor within the Car class definition
- default constructor
- copy constructor
- other constructors
- destructor
-
FreightCar constructors and destructor within the FreightCar class definition
- default constructor
- copy constructor
- other constructors
- destructor
-
PassengerCar constructors and destructor within the PassengerCar class definition
- default constructor
- copy constructor
- other constructors
- destructor
-
StringOfCars constructors and destructor within the StringOfCar class definition
- default constructor
- copy constructor (always copies only Car objects in this implementation - do not use)
- other constructors
- destructor
- main
-
Car member functions declared within the Car class but defined later
- setup
- output
- operator=
- setKind
-
FreightCar member functions declared within the FreightCar class but defined later
- operator=
- setKind
-
PassengerCar member functions declared within the PassengerCar class but defined later
- operator=
- setKind
- operator== friend of Car
-
StringOfCars member functions declared within the StringOfCars class but defined later
- output
- push for Car objects
- push for FreightCar objects
- push for PassengerCar objects
- pop (always returns only Car objects in this implemntation - do not use)
- input
In this problem we will use the StringOfCars class to contain Car, FreightCar, and PassengerCar objects all in the same string of cars. This works because a pointer of type Car * can point to Car objects as well as point to the child FreightCar and PassengerCar objects.
Because we have pointers of type Car * that may point to any one of the three types of objects, a StringOfCars object does not know which type object will be encountered until execution time. The mechanism to select the correct version of the function at execution time, rather than having it fixed at compile time, is to use virtual functions. That is why we made the setKind and destructor functions virtual earlier in this assignment.
In the input function loop read one line from the file each time throught the loop, look at the Type field in the record. If the type is Car create a Car object and call the push function to put it in the StringOfCars object. Similarly if the type is FreightCar, create and push a FreightCar object. If it is a PassengerCar, create and push a PassengerCar object.
We have a push member function that accepts a Car parameter, creates a copy of the Car parameter that is a Car object in the heap, then puts the pointer to that Car object into the array. Build another member function, also named push, that takes a FreightCar parameter, creates a FreightCar in the heap, and then puts the pointer to that FreightCar object into the array. Also build a similar member function for a PassengerCar.
The file for this problem should contain:
Type order ARR number kind loaded destination Car car1 CN 819481 maintenance false NONE Car car2 SLSF 46871 business true Memphis Car car3 AOK 156 tender true McAlester FreightCar car4 MKT 123456 tank false Fort Worth FreightCar car5 MP 98765 box true Saint Louis FreightCar car6 SP 567890 flat true Chicago FreightCar car7 GMO 7878 hopper true Mobile PassengerCar car8 KCS 7893 chair true Kansas City PassengerCar car9 PAPX 145 sleeper true Tucson PassengerCar car10 GN 744 combine false NONE
Remove the code from the main funtion and replace it with the following
Define a StringOfCars object in the stack.
Then pass that object to the input function.
Then call the output function for that object.
You may note that the pop member function and copy constructor for a StringOfCars do not determine what type of car is being retrieved. Fixing this problem is more than what I want you to do in the assignment. So, ignore this problem and do not use the pop member function and the copy constructor for the StringOfCars class.