#include <iostream> #include <fstream> using namespace std; class Car { protecte
ID: 3920487 • Letter: #
Question
#include <iostream>
#include <fstream>
using namespace std;
class Car
{
protected:
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);
}
virtual ~Car() {}
friend bool operator==(const Car &car1, const Car &car2);
void setUp(string reportingMark, int carNumber, string kind, bool loaded, string destination);
void output();
virtual void setKind(string &kind);
Car & operator=(const Car & carB);
};
class FreightCar : public Car
{
public:
FreightCar():Car()
{
setUp("", 0, "otherFreight", false, "NONE");
};
FreightCar(const FreightCar &c):Car(c)
{
setUp(c.reportingMark, c.carNumber, c.kind, c.loaded, c.destination);
};
FreightCar(string reportingMark, int carNumber, string kind, bool loaded, string destination):Car(reportingMark, carNumber, kind, loaded, destination)
{
setUp(reportingMark, carNumber, kind, loaded, destination);
};
void setKind(string &k);
FreightCar & operator=(const FreightCar & carB);
};
class PassengerCar : public Car
{
public:
PassengerCar():Car()
{
setUp("", 0, "otherPassenger", false, "NONE");
};
PassengerCar(const PassengerCar &c):Car(c)
{
setUp(c.reportingMark, c.carNumber, c.kind, c.loaded, c.destination);
};
PassengerCar(string reportingMark, int carNumber, string kind, bool loaded, string destination):Car(reportingMark, carNumber, kind, loaded, destination)
{
setUp(reportingMark, carNumber, kind, loaded, destination);
};
void setKind(string &k);
PassengerCar & operator=(const PassengerCar & carB);
};
class StringOfCars
{
private:
static const int ARRAY_SIZE = 10;
Car **ptr;
int carCount;
public:
StringOfCars()
{
ptr = new Car*[ARRAY_SIZE];
for(int i = 0; i < ARRAY_SIZE; i++){
ptr[i] = 0;
}
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()
{
for(int i = 0; i < carCount; i++)
{
pop(*ptr[i]);
}
delete [] ptr;
}
void push(const Car &c);
void push(const FreightCar &c);
void push(const PassengerCar &c);
void pop(Car &c);
void output();
};
void input(StringOfCars &soc);
int main()
{
StringOfCars soc;
input(soc);
soc.output();
}
/*Takes 5 parameters by value: reporting mark, car number, kind, loaded, and destination
Inputs these paramaters into the Car class' variables
*/
void Car::setUp(string rm, int cn, string k, bool l, string d)
{
reportingMark = rm;
carNumber = cn;
kind = k;
loaded = l;
destination = d;
(*this).setKind(k);
}
/* Prints the reporting mark, car number, kind, loaded, and destination in a neat format
*/
void Car::output()
{
string isLoaded;
if(loaded) isLoaded = "true";
else isLoaded = "false";
cout << " Reporting Mark: " << reportingMark << " Car Number: " << carNumber << " Kind: " << kind << " Car is loaded: " << isLoaded << " Destination: " << 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;
}
/*sets the 'kind' field for the Car object
*/
void Car::setKind(string &k)
{
if(k != "business" && k != "maintenance") kind = "other";
}
/*sets the values in the left hand object from the right hand object
*/
FreightCar & FreightCar::operator=(const FreightCar & carB)
{
setUp(carB.reportingMark, carB.carNumber, carB.kind, carB.loaded, carB.destination);
return * this;
}
/*sets the 'kind' field for the FreightCar object
*/
void FreightCar::setKind(string &k)
{
if(k != "box" && k != "tank" && k != "flat") kind = "otherFreight";
}
/* sets the values in the left hand object from the right hand object
*/
PassengerCar & PassengerCar::operator=(const PassengerCar & carB)
{
setUp(carB.reportingMark, carB.carNumber, carB.kind, carB.loaded, carB.destination);
return * this;
}
/* *sets the 'kind' field for the PassengerCar object
*/
void PassengerCar::setKind(string &k)
{
if(k != "chair" && k != "sleeper") kind = "otherPassenger";
}
/* 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);
}
/* 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(const Car &c)
{
Car*car = new Car;
*car = c;
if(carCount < ARRAY_SIZE)
{
ptr[carCount] = car;
carCount++;
}
else cout << "Car array is full, cannot add car";
}
/*Adds FreightCar to StringOfCars array
*/
void StringOfCars::push(const FreightCar &c)
{
FreightCar*car = new FreightCar;
*car = c;
if(carCount < ARRAY_SIZE)
{
ptr[carCount] = car;
carCount++;
}
else cout << "Car array is full, cannot add car";
}
/* Adds PassengerCar to StringOfCars array
*/
void StringOfCars::push(const PassengerCar &c)
{
PassengerCar*car = new PassengerCar;
*car = c;
if(carCount < ARRAY_SIZE)
{
ptr[carCount] = car;
carCount++;
}
else cout << "Car array is full, cannot add car";
}
/* Removes car from StringOfCars array and saves it into a different car object
*/
void StringOfCars::pop(Car &c)
{
if(carCount == 0) cerr << "ERROR: No cars in String of Cars";
else
{
c = *ptr[carCount - 1];
delete ptr[carCount - 1];
carCount--;
}
}
/*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, order;
int carNumber;
bool loaded;
string loadedString;
ifstream inputFile;
inputFile.open("input.txt");
if(!inputFile.is_open())
{
fprintf(stderr, "Error Opening File ");
exit(1);
}
while(inputFile.peek() != EOF)
{
inputFile >> carType >> order >> 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 if(carType == "FreightCar")
{
FreightCar temp(reportingMark, carNumber, kind, loaded, destination);
soc.push(temp);
}
else if (carType == "PassengerCar")
{
PassengerCar temp(reportingMark, carNumber, kind, loaded, destination);
soc.push(temp);
}
else
{
cerr << " Error: carType not 'Car' ";
}
}
inputFile.close();
}
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.
Explanation / Answer
/* Almost all the required modifications mentioned in section 5.2 is already done
except testing of copy constructor. That ahs been added now. pop member function
has been omitted now.
*/
#include <iostream>
#include <fstream>
#include <stdlib.h>
using namespace std;
class Car
{
protected:
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);
}
virtual ~Car() {}
friend bool operator==(const Car &car1, const Car &car2);
void setUp(string reportingMark, int carNumber, string kind, bool loaded, string destination);
void output();
virtual void setKind(string &kind);
Car & operator=(const Car & carB);
};
class FreightCar : public Car
{
public:
FreightCar():Car()
{
setUp("", 0, "otherFreight", false, "NONE");
};
FreightCar(const FreightCar &c):Car(c)
{
setUp(c.reportingMark, c.carNumber, c.kind, c.loaded, c.destination);
};
FreightCar(string reportingMark, int carNumber, string kind, bool loaded, string destination):Car(reportingMark, carNumber, kind, loaded, destination)
{
setUp(reportingMark, carNumber, kind, loaded, destination);
};
void setKind(string &k);
FreightCar & operator=(const FreightCar & carB);
};
class PassengerCar : public Car
{
public:
PassengerCar():Car()
{
setUp("", 0, "otherPassenger", false, "NONE");
};
PassengerCar(const PassengerCar &c):Car(c)
{
setUp(c.reportingMark, c.carNumber, c.kind, c.loaded, c.destination);
};
PassengerCar(string reportingMark, int carNumber, string kind, bool loaded, string destination):Car(reportingMark, carNumber, kind, loaded, destination)
{
setUp(reportingMark, carNumber, kind, loaded, destination);
};
void setKind(string &k);
PassengerCar & operator=(const PassengerCar & carB);
};
class StringOfCars
{
private:
static const int ARRAY_SIZE = 10;
Car **ptr;
int carCount;
public:
StringOfCars()
{
ptr = new Car*[ARRAY_SIZE];
for(int i = 0; i < ARRAY_SIZE; i++){
ptr[i] = 0;
}
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()
{
for(int i = 0; i < carCount; i++)
{
delete ptr[i];
}
delete [] ptr;
}
void push(const Car &c);
void push(const FreightCar &c);
void push(const PassengerCar &c);
//void pop(Car &c);
void output();
};
void input(StringOfCars &soc);
int main()
{
StringOfCars soc;
input(soc);
soc.output();
StringOfCars soc1(soc);
soc1.output();
}
/*Takes 5 parameters by value: reporting mark, car number, kind, loaded, and destination
Inputs these paramaters into the Car class' variables
*/
void Car::setUp(string rm, int cn, string k, bool l, string d)
{
reportingMark = rm;
carNumber = cn;
kind = k;
loaded = l;
destination = d;
(*this).setKind(k);
}
/* Prints the reporting mark, car number, kind, loaded, and destination in a neat format
*/
void Car::output()
{
string isLoaded;
if(loaded) isLoaded = "true";
else isLoaded = "false";
cout << " Reporting Mark: " << reportingMark << " Car Number: " << carNumber << " Kind: " << kind << " Car is loaded: " << isLoaded << " Destination: " << 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;
}
/*sets the 'kind' field for the Car object
*/
void Car::setKind(string &k)
{
if(k != "business" && k != "maintenance") kind = "other";
}
/*sets the values in the left hand object from the right hand object
*/
FreightCar & FreightCar::operator=(const FreightCar & carB)
{
setUp(carB.reportingMark, carB.carNumber, carB.kind, carB.loaded, carB.destination);
return * this;
}
/*sets the 'kind' field for the FreightCar object
*/
void FreightCar::setKind(string &k)
{
if(k != "box" && k != "tank" && k != "flat") kind = "otherFreight";
}
/* sets the values in the left hand object from the right hand object
*/
PassengerCar & PassengerCar::operator=(const PassengerCar & carB)
{
setUp(carB.reportingMark, carB.carNumber, carB.kind, carB.loaded, carB.destination);
return * this;
}
/* *sets the 'kind' field for the PassengerCar object
*/
void PassengerCar::setKind(string &k)
{
if(k != "chair" && k != "sleeper") kind = "otherPassenger";
}
/* 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);
}
/* 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(const Car &c)
{
Car*car = new Car;
*car = c;
if(carCount < ARRAY_SIZE)
{
ptr[carCount] = car;
carCount++;
}
else cout << "Car array is full, cannot add car";
}
/*Adds FreightCar to StringOfCars array
*/
void StringOfCars::push(const FreightCar &c)
{
FreightCar*car = new FreightCar;
*car = c;
if(carCount < ARRAY_SIZE)
{
ptr[carCount] = car;
carCount++;
}
else cout << "Car array is full, cannot add car";
}
/* Adds PassengerCar to StringOfCars array
*/
void StringOfCars::push(const PassengerCar &c)
{
PassengerCar*car = new PassengerCar;
*car = c;
if(carCount < ARRAY_SIZE)
{
ptr[carCount] = car;
carCount++;
}
else cout << "Car array is full, cannot add car";
}
/* Removes car from StringOfCars array and saves it into a different car object
*/
/*
void StringOfCars::pop(Car &c)
{
if(carCount == 0) cerr << "ERROR: No cars in String of Cars";
else
{
c = *ptr[carCount - 1];
delete ptr[carCount - 1];
carCount--;
}
}
*/
/*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, order;
int carNumber;
bool loaded;
string loadedString;
ifstream inputFile;
inputFile.open("input.txt");
if(!inputFile.is_open())
{
fprintf(stderr, "Error Opening File ");
exit(1);
}
while(inputFile.peek() != EOF)
{
inputFile >> carType >> order >> 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 if(carType == "FreightCar")
{
FreightCar temp(reportingMark, carNumber, kind, loaded, destination);
soc.push(temp);
}
else if (carType == "PassengerCar")
{
PassengerCar temp(reportingMark, carNumber, kind, loaded, destination);
soc.push(temp);
}
else
{
cerr << " Error: carType not 'Car' ";
}
}
inputFile.close();
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.