Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

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

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 funtions: 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.

///////PROBLEM 5.1//////

/* ************************************************************Beginning of Global Area********************************************************************* */ #include #include #include #include #include #include #include

using namespace std;

enum Kind { business, maintenance, other, box, tank, flat, hopper, otherFreight, chair, sleeper, otherPassenger }; const string KIND_ARRAY[] = { "business", "maintenance", "other", "box", "tank", "flat", "hopper" , "otherFreight", "chair", "sleeper", "otherPassenger" };

/* *************** START of Class Car ****************************** */ class Car { protected: static const int FIELD_WIDTH = 22; std::string reportingMark; int carNumber; Kind kind; bool loaded; public: std::string destination; friend bool operator==(const Car &carA, const Car &carB);

/* ******* default constructor ***** */ Car() { setUp("", 0, "other", false, "NONE"); }

/* *** copy constructor ************ */ Car(const Car &oldCar) { setUp(oldCar.reportingMark, oldCar.carNumber, KIND_ARRAY[oldCar.kind], oldCar.loaded, oldCar.destination); kind = oldCar.kind; }

/* *** input constructor *********** */ Car(const string &reportingMark, const int &carNumber, const string &kind, const bool &loaded, const string &destination) { setUp(reportingMark, carNumber, kind, loaded, destination); }

int getCarNum() { return carNumber; }

string getRepMark() { return reportingMark; }

/* ************** Output ***************** -Prints Data to the console by calling the object */ void output() { std::cout << std::setw(FIELD_WIDTH) << std::left << "Reporting Mark: " << std::setw(FIELD_WIDTH) << reportingMark << std::endl; std::cout << std::setw(FIELD_WIDTH) << "Car Number: "<< std::setw(FIELD_WIDTH) << carNumber<< std::endl; std::cout << std::setw(FIELD_WIDTH) << "Kind: "<< std::setw(FIELD_WIDTH) << KIND_ARRAY[kind]<< std::endl; std::cout << std::setw(FIELD_WIDTH) << "Loaded: "<< std::setw(FIELD_WIDTH); if(loaded) { std::cout << "true" << std::endl; } else { std::cout << "false" << std::endl; } std::cout << std::setw(FIELD_WIDTH) << "Destination: "<< std::setw(FIELD_WIDTH) << destination<< std::endl; std::cout << std::endl; }

/* ************ setKind *********************** -will set the correct kind */ void setKind(const string & stringKind) { if (stringKind == "business") { kind = business; } else if (stringKind == "maintenance") { kind = maintenance; } else { kind = other; } }

/* ************ setUp *********************** -takes in information given by the user -it then stores the information in the car objects variables */ void setUp(string rMark, int carNum, string carKind, bool isLoaded, string dest) { reportingMark = rMark; carNumber = carNum; setKind(carKind); loaded = isLoaded; destination = dest; }

/* ************ Operator= ******************** -overload member function that returns the left hand operator by reference */ Car & operator=(const Car & carB) { setUp(carB.reportingMark, carB.carNumber, KIND_ARRAY[carB.kind], carB.loaded, carB.destination); return *this; } }; /* *************** END of Class Car ********************************* */

/* *************** START of Derived Class FreightCar **************** */ class FreightCar : public Car { public: /* ******* default constructor ***** */ FreightCar() { setUp("", 0, "other", false, "NONE"); }

/* *** copy constructor ************ */ FreightCar(const FreightCar &ofFrght) { setUp(ofFrght.reportingMark, ofFrght.carNumber, KIND_ARRAY[ofFrght.kind], ofFrght.loaded, ofFrght.destination); }

/* *** input constructor *********** */ FreightCar(const string &rpmrk, const int &cNumber, const string &knd, const bool &lded, const string &des) { setUp(rpmrk, cNumber, knd, lded, des); }

/* ************** FreightCar::setKind ******* -Takes in data and assigns to variable kind */ void setKind(const string & stringKind) { if (stringKind == "box") { kind = box; } else if (stringKind == "tank") { kind = tank; } else if (stringKind == "flat") { kind = flat; } else if (stringKind == "hopper") { kind = hopper; } else { kind = otherFreight; } } }; /* *************** END of Derived Class FreightCar ******************** */

/* *************** START of Derived Class PassengerCar **************** */ class PassengerCar : public Car { public: /* ******* default constructor ***** */ PassengerCar() { setUp("", 0, "other", false, "NONE"); }

/* *** copy constructor ************ */ PassengerCar(const PassengerCar &oldPas) { setUp(oldPas.reportingMark, oldPas.carNumber, KIND_ARRAY[oldPas.kind], oldPas.loaded, oldPas.destination); }

/* *** input constructor *********** */ PassengerCar(const string &rm, const int &cNumber, const string &knd, const bool &lded, const string &des) { setUp(rm, cNumber, knd, lded, des); }

/* ************** PassengerCar::setKind ******* -Takes in data and assigns to variable kind */ void setKind(const string & stringKind) { if (stringKind == "chair") { kind = chair; } else if (stringKind == "sleeper") { kind = sleeper; } else { kind = otherPassenger; } } }; /* *************** END of Derived Class PassengerCar **************** */

/* ********************** START of Class Node ********************** */ class Node { private: Node * nxt; Car * data;

/* ******* default constructor ***** */ Node() { nxt = nullptr; data = nullptr; } public: friend class StringOfCars;

}; /* ******************** END of Class Node *************************** */

/* *************** START of Class StringOfCars ********************** */ class StringOfCars { private: Node * head; Node * tail; public: StringOfCars() { head = nullptr; tail = nullptr; }

StringOfCars(const StringOfCars & oldstrngCar) { Node * currentNodePtr = oldstrngCar.head; head = nullptr; tail = nullptr;

if (oldstrngCar.head != nullptr) { while (currentNodePtr != nullptr) { push(*currentNodePtr->data); currentNodePtr = (*currentNodePtr).nxt; } } }

/* ********* Destructor ***********/ ~StringOfCars() {}

/* ******************** output ******************** prints the cars inside the string of cars along with its heading. */ void output() { Node * currentNodePtr; if (head == nullptr) { cout << "No cars "; } else { currentNodePtr = head; int currentCarNumber = 0; while (currentNodePtr != nullptr) { cout << "Car Number " << ++currentCarNumber << endl; (*currentNodePtr->data).output(); currentNodePtr = (*currentNodePtr).nxt; } } }

/* ******************** push ******************** adds a car to the string of cars */ void push(const Car & tempCar) { Car* currentCarPtr = new Car(tempCar); Node* currentNodePtr = new Node;

(*currentNodePtr).data = currentCarPtr;

if (head == nullptr) { head = currentNodePtr; tail = currentNodePtr; } else { (*tail).nxt = currentNodePtr; tail = currentNodePtr; } } }; /* *************** END of Class StringOfCars ********************************* */

/* ************************* START Function Prototypes *********************** */ void input(StringOfCars & carArray); void buildCar(string rMark, int carNum, string carKind, bool isLoaded, string dest, StringOfCars & carArray); void buildFreightCar(string rMark, int carNum, string carKind, bool isLoaded, string dest, StringOfCars & carArray); void buildPassengerCar(string rMark, int carNum, string carKind, bool isLoaded, string dest, StringOfCars & carArray); /* ************************* END Function Prototypes ************************ */

/* ***************** operator == ***************** -tests for equality between two Car objects based on the input for variables reportingMark and carNumber */ bool operator==(const Car &carA, const Car &carB) { bool temp; if (carA.reportingMark == carB.reportingMark && carA.carNumber == carB.carNumber) { temp = true; } else { temp = false; } return temp; }

/* ******************** input ******************** -takes the carType, reportingMark, carNumber, kind, loaded and destination from file -Pushes car data to String Of Cars */ void input(StringOfCars & carArray) { string type; string order; string rMark; int carNum; string carKind; bool isLoaded; string dest; ifstream inputFile;

inputFile.open("cardata51.txt");

if (!inputFile) { cerr << "Error while opening the file. Error code 1" << endl; exit(1); }

while (inputFile.peek() != EOF) { inputFile >> type; inputFile >> order; inputFile >> rMark; inputFile >> carNum; inputFile >> carKind;

string temp; inputFile >> temp; if (temp == "true") { isLoaded = true; } else if (temp == "false") { isLoaded = false; }

while (inputFile.peek() == ' ') { inputFile.get();

getline(inputFile, dest);

if (type == "Car") { buildCar(rMark, carNum, carKind, isLoaded, dest, carArray); } else if (type == "FreightCar") { buildFreightCar(rMark, carNum, carKind, isLoaded, dest, carArray); } else if (type == "PassengerCar") { buildPassengerCar(rMark, carNum, carKind, isLoaded, dest, carArray); } } } inputFile.close(); }

/* ******************** buildCar ******************** -builds an object of type car using the car constructor */ void buildCar(string rMark, int carNum, string carKind, bool isLoaded, string dest, StringOfCars & carArray) { Car obj = Car(rMark, carNum, carKind, isLoaded, dest); carArray.push(obj); }

/* ******************** buildFreightCar ******************** -builds an object of type FreightCar using the FreightCar constructor */ void buildFreightCar(string rMark, int carNum, string carKind, bool isLoaded, string dest, StringOfCars & carArray) { FreightCar obj = FreightCar(rMark, carNum, carKind, isLoaded, dest); carArray.push(obj); }

/* ******************** buildPassengerCar ******************** -builds an object of type PassengerCar using the PassengerCar constructor */ void buildPassengerCar(string rMark, int carNum, string carKind, bool isLoaded, string dest, StringOfCars & carArray) { PassengerCar obj = PassengerCar(rMark, carNum, carKind, isLoaded, dest); carArray.push(obj); } /* *****************************************************End of Global Area******************************************************** */

/* **************** Main ******************* */ int main() { StringOfCars stringOfCars1; input(stringOfCars1);

StringOfCars stringOfCars2(stringOfCars1); stringOfCars2.output(); }

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

Step: 3

blur-text-image

Ace Your Homework with AI

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

Get Started

Students also viewed these Databases questions