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.

  1. Car constructors and destructor within the Car class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  2. StringOfCars constructors and destructor within the StringOfCar class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  3. main
  4. Car member functions declared within the Car class but defined later
    1. setup
    2. output
    3. operator=
  5. StringOfCars member functions declared within the StringOfCars class but defined later
    1. output
    2. push
    3. pop
  6. global functions
    1. operator==   with Car parameters
    2. 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.

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.

  1. Car constructors and destructor within the Car class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  2. FreightCar constructors and destructor within the FreightCar class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  3. PassengerCar constructors and destructor within the PassengerCar class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  4. StringOfCars constructors and destructor within the StringOfCar class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  5. main
  6. Car member functions declared within the Car class but defined later
    1. setup
    2. output
    3. operator=
    4. setKind
  7. FreightCar member functions declared within the FreightCar class but defined later
    1. operator=
    2. setKind
  8. PassengerCar member functions declared within the PassengerCar class but defined later
    1. operator=
    2. setKind
  9. operator== friend of Car
  10. StringOfCars member functions declared within the StringOfCars class but defined later
    1. output
    2. push
    3. pop
  11. 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.

  1. Car constructors and destructor within the Car class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  2. FreightCar constructors and destructor within the FreightCar class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  3. PassengerCar constructors and destructor within the PassengerCar class definition
    1. default constructor
    2. copy constructor
    3. other constructors
    4. destructor
  4. StringOfCars constructors and destructor within the StringOfCar class definition
    1. default constructor
    2. copy constructor (always copies only Car objects in this implementation - do not use)
    3. other constructors
    4. destructor
  5. main
  6. Car member functions declared within the Car class but defined later
    1. setup
    2. output
    3. operator=
    4. setKind
  7. FreightCar member functions declared within the FreightCar class but defined later
    1. operator=
    2. setKind
  8. PassengerCar member functions declared within the PassengerCar class but defined later
    1. operator=
    2. setKind
  9. operator== friend of Car
  10. StringOfCars member functions declared within the StringOfCars class but defined later
    1. output
    2. push for Car objects
    3. push for FreightCar objects
    4. push for PassengerCar objects
    5. pop (always returns only Car objects in this implemntation - do not use)
  11. 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.