Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

i n C++ please and thank you . I understand it's a bit to read but any help is appreciated. Problem 5.1 Copy the solution

in C++ please and thank you. I understand it's a bit to read but any help is appreciated.

Problem 5.1

Copy the solution from problem 4.2

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 . You are not using a StringOfCars in this problem, but will need it later. You can remove the StringOfCars from the parameter list for the input function and put it back later, or keep the StringOfCars parameter, pass a StringOfCars to the input function, and ignore it.

As a preliminary step, create a new global function (that is a function that is not a member function) named buildCar.

The buildCar function has the five parameters needed for a Car. When called, it builds an object of type Car by using the Car constructor that has five parameters. For testing in this assignment, after building the car object, the buildCar function calls the output member function for the Car.

Now, modify the input function so it calls the buildCar function to build the car, rather than building the car in the input function.

The kind of cars for the three classes will be: Car: business, maintenance, other FreightCar: box, tank, flat, otherFreight PassengerCar: chair, sleeper, otherPassenger

Use an enum to keep the kind, rather than using a string as we did in previous problems.

In the global area define an enum named Kind, with the following values in this order: business, maintenance, other, box, tank, flat, otherFreight, chair, sleeper, otherPassenger Also in the global area define an array of const string objects named KIND_ARRAY. It will contain strings with the same text as the names of the values in the enum, in the same order.

Change the Kind field in the Car class so it is: Kind kind; Adjust the functions to use the enum and KIND_ARRAY. The output function can use the KIND_ARRAY values to print the string corresponding to the enum value.

Build a new member function setKind. in the Car::setUpCar functionm pass it a constant reference to the string provided by the user. If the string is not business or maintenance in the Car class, set the kind to other. The setKind member function will set the correct Kind.

Change private to protected in the Car class only.

Make two classes that inherit from the Car class: FreightCar and PassengerCar. Each class will need a default constructor, a copy constructor, and a constructor that has five parameters. Only one more function will be built in each class; all the rest will be inherited. No additional member data will be added.

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

Create two new global function named buildFreightCar and buildPassengerCar, similar to the buildCar function. These are used to build a FreightCar or a Passenger car, respectively.

Revise the main function to call the input function and do nothing else.

In the input function loop read one line from the file each time through the loop, look at the Type field in the record and call the corresponding build function to build that type of car. Before calling the appropriate build function, print a header giving the sequence number of the car read, with the number 1 for the first car and incremented for each successive car.

The file for this problem is called cardata5.txt, and must contain:

Car car1 CN 819481 maintenance false NONE

Car car2 SLSF 46871 business true Memphis

Car car3 AOK 156 tender true Pierre

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 Tuscaloosa

PassengerCar car8 KCS 7893 chair true Kansas City

PassengerCar car9 PAPX 145 sleeper true Tucson

PassengerCar car10 GN 744 combine false NONE

Problem 5.2

Copy the solution from problem 5.1.

In this problem you will change the StringOfCars class so it has an array of pointers to objects, rather than an array of objects themselves. This will allow us to have a string of cars that contains Car, FreightCar, and PassengerCar objects all in the same string of cars. This works because a pointer of type Car * can be made to point to Car objects as well as point to the child FreightCar and PassengerCar objects.

Remove the call to the output member function from the three build functions: buildCar, buildFreightCar, and buildPassengerCar.

Because you have pointers of type Car * that may point to any one of the three types of objects, there is a problem. The system does not know what type object will be encountered until execution time. That means a system is needed so the functions that are overridden need to have a mechanism to select the correct version of the function at execution time, rather than having it fixed at compile time. This is done with the virtual declaration. To do this make the declaration of the setKind and the declaration of the ~Car functions virtual in the Car class. This is only done in the declaration, not the definition of the function. This is only done in the parent class, not the children classes.

To change the class StringOfCars, comment out all the code in the member functions of the StringOfCars class and fix them one or two at a time in the following order. These are similar to the previous functions, but changed to allow for the fact that we are putting pointers to cars in the array.

Build the default constructor first. Create a default string of cars in main.

Build an output function, similar to the old one, but dereferrencing the pointers.

Write a push function which adds a car to the string of cars. It takes a Car by constant reference, allocates space in the heap, makes a copy of the Car, and puts the pointer to the Car in the array.

Write a copy constructor similar to the old one, but it gets space for each car and copies each one, as well as getting space for the array.

omit the pop member function.

Add to the build functions a call to push the objects onto the string of cars.

Remove the output from the build functions.

Test the copy constructor by making stringOfCars2 in the stack for main that is a copy of stringOfCars1.

Print stringOfCars2.

CODE FROM 4.2

#include

#include

using namespace std;

class Car

{

private:

int carNumber;

bool loaded;

string reportingMark, kind, destination;

public:

Car()

{

setUp("", 0, "other", false, "NONE");

}

Car(const Car &c)

{

setUp(c.reportingMark, c.carNumber, c.kind, c.loaded, c.destination);

}

Car(string reportingMark, int carNumber, string kind, bool loaded, string destination)

{

setUp(reportingMark, carNumber, kind, loaded, destination);

}

~Car() {}

friend bool operator==(const Car &car1, const Car &car2);

void setUp(string reportingMark, int carNumber, string kind, bool loaded, string destination);

void output();

Car & operator=(const Car & carB);

};

class StringOfCars

{

private:

static const int ARRAY_SIZE = 10;

Car *ptr;

int carCount;

public:

StringOfCars()

{

ptr = new Car[ARRAY_SIZE];

carCount = 0;

}

StringOfCars(const StringOfCars &c)

{

ptr = new Car[ARRAY_SIZE];

carCount = c.carCount;

for(int i = 0; i < ARRAY_SIZE; i++){

ptr[i] = c.ptr[i];

}

}

~StringOfCars()

{

delete [] ptr;

}

void push(Car &c);

void pop(Car &c);

void output();

};

void input(StringOfCars &soc);

int main()

{

cout << "Test 1:" << endl;

Car car1("SP", 34567, "business", 1, "Salt Lake City");

Car car2;

car2 = car1;

car2.output();

cout << " Test 2: " << endl;

StringOfCars string1;

input(string1);

cout << "STRING 1:" << endl;

string1.output();

cout << " Test 3: " << endl;

Car car3;

string1.pop(car3);

cout << "CAR 3:" << endl;

car3.output();

cout << " STRING 1:" << endl;

string1.output();

}

void Car::setUp(string rm, int cn, string k, bool l, string d)

{

reportingMark = rm, carNumber = cn, kind = k, loaded = l, destination = d;

}

//Prints reporting mark, car number, loaded, kind, destination

void Car::output()

{

string isLoaded;

if(loaded) isLoaded = "true";

else isLoaded = "false";

cout << " Reporting Mark: \t" << reportingMark << " Car Number: \t\t" << carNumber << " Kind: \t\t\t\t" << kind << " Car is loaded: \t\t" << isLoaded << " Destination: \t\t" << destination << endl;

}

//sets the values in the left hand object from the right hand object

Car & Car::operator=(const Car & carB)

{

setUp(carB.reportingMark, carB.carNumber, carB.kind, carB.loaded, carB.destination);

return * this;

}

//Prints out car objects in StringOfCars array

void StringOfCars::output()

{

if(carCount == 0) cout << "NO cars";

for(int i = 0; i < carCount; i++)

{

cout << " Car Number: " << i + 1 << endl;

ptr[i].output();

}

}

//Adds car to StringOfCars array

void StringOfCars::push(Car &c)

{

if(carCount < ARRAY_SIZE)

{

ptr[carCount] = c;

carCount++;

}

else cout << "Car array is full, cannot add car";

}

void StringOfCars::pop(Car &c)

{

if(carCount == 0) cout << "ERROR: No cars in String of Cars";

else

{

c = ptr[carCount - 1];

carCount--;

}

}

//Compares two car objects to see if they equal

bool operator==(const Car &car1, const Car &car2)

{

return (car1.reportingMark == car2.reportingMark && car1.carNumber == car2.carNumber);

}

/*

Takes the reporting mark, car number, kind, loaded, and destination as value parameters

Values read from a text file

*/

void input(StringOfCars &soc)

{

string reportingMark, kind, destination, carType;

int carNumber;

bool loaded;

string loadedString;

ifstream inputFile;

inputFile.open("Car.txt");

if(!inputFile.is_open())

{

fprintf(stderr, "Error Opening File ");

exit(1);

}

while(inputFile.peek() != EOF)

{

inputFile >> carType >> reportingMark >> carNumber >> kind >> loadedString;

if(loadedString == "true") loaded = true;

else if(loadedString == "false") loaded = false;

else cout << "There has been a problem with loaded";

while(inputFile.peek() == ' ')

{

inputFile.get();

}

getline(inputFile, destination, ' ');

if(carType == "Car")

{

Car temp(reportingMark, carNumber, kind, loaded, destination);

soc.push(temp);

}

else

{

cout << " Error: carType not 'Car' ";

}

}

inputFile.close();

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

More Books

Students also viewed these Databases questions

Question

Describe Freuds view of personality.

Answered: 1 week ago

Question

Identify the types of informal reports.

Answered: 1 week ago

Question

Write messages that are used for the various stages of collection.

Answered: 1 week ago