Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

I need you to revise Shapes.cpp and add iShapes.cpp and iShapes.h which are following these orders. If you think there is no enough information, please

I need you to revise Shapes.cpp and add iShapes.cpp and iShapes.h which are following these orders. If you think there is no enough information, please ask me what types of information is missing. Thank you.

Before the orders, you will rewrite the Prism class to inherit from Triangle. Prism will inherit one dimension from Triangle, but will add a 2nd. If we name that 2nd attribute height , I write an inline constructor for the new Prism class with a constant string vector of tokens as the one and only parameter for both class' constructors.

class Triangle { protected public: double side; void output(ostream&); }; class Prism : public Triangle { const double height; public: double side; double height; void output(ostream&); const; }; class Prism { ... Box(const vector& tokens): Rectangle(tokens), height(...){ } ... }; Prism::Prism(vector token): Triangle(token), height((token.size() >= 3) ? atof(token[2].c_str()) : 0) { }

1. Lose The Sorting Code Block

We really only added the nested-for-loop sorting to show that we could. Now it's time to lose that -- remove that code block from the main program.

2. 3D Shapes Are 2D Shapes Projected Into 3D

Easy to say -- less easy to do. Make each 3D class a child of it's related 2D class. The 3D's are to inherit the private members that they have in common with their parent, and only add a data member if it's one the parent does not already have. That is, the 3D Cylinder class should adda private data member for height.

3. A Multi-File Solution

In a coming module we will use the shape classes in an entirely different application -- one involving a "graphical user interface" (GUI) with typed input from a user, and no input from a TXT file. In preparation for that, separate the class coding into a CPP and an H file.

Do not make separate CPP and H file pairs for each class -- that's certainly possible and there's really nothing wrong with doing so, but this is an opportunity to show an alternative way to organize class files. When there are many small and similar classes, this can be a good way to organize.

To do this, create an H file named iShapes.h and move all the class definitions and supporting function prototypes (if any) there. Create a CPP named iShapes.cpp and move all the class functions and supporting functions (if any) there. (The "i" prefix is to identify these files as the ones using inheritance, because it the next lab, these will change with the introduction of polymorphism.)

The manipulators are needed only in iShapes.cpp -- not in the main program. In fact, they don't even need prototypes (because they are unique to this CPP). Just place them above the other functions that call them. If you prefer to use prototypes, you may do so either in the H (to make them available throughout the app) or in the CPP (to be unique to that CPP).

Hints:

Include identification comment blocks in all files, so the grader knows whose work he's looking at.

Each CPP and H stands on its own with regard to library includes. That is if "string" appears in a file, it better include the string library, and because it includes a C++ library, it better have using namespace too. Each file may have its own C++ and C library code blocks.

Include the #ifndef container in the H.

The "parseString" function is not needed by the classes. It's only needed in the main program and that's where it and its prototype should be.

4. A Bag Of Shapes

Once you have all this working, let's work on the bag. So far the bag has entirely generic pointers. They can point to anything. We canput anything in that bag. But remember "least privilege"? And do we really need the privilege of bagging just anything? Really, all we need is to bag shapes -- only shapes.

Here's how to add that refinement to our bag so that it's now a bag of shapes.

1. Create a class named struct Shape with no members. Save, compile, and run.

2. One-by-one, make each 2D shape a child of struct Shape . Save, compile, and run.

3. Now change all references to void* to Shape* .Save, compile, and run -- that's it!

In doing this we're saying that a Square is a Shape, and a Cube is a Square, and similar for the other shapes. We've always been able to make a generic pointer point to a Square. But now, because a Square is-a Shape, we are able to make Shape pointers point to Squares and any other child (2D) or grandchild (3D) shape!

Shapes.input.txt

SQUARE 14.5 SQUARE RECTANGLE 14.5 4.65 CIRCLE 14.5 CUBE 13 BOX 1 2 3 SPHERE 2.4 CYLINDER 1.23 CYLINDER 50 1.23 TRIANGLE 1.2 3.2 EOF 

Shapes.cpp

#include #include #include  #include  #include  #include  #include  #include  #include  using namespace std; //Global constant for PI const double PI = 3.14159; class Square { const double length; public : Square(const vector&tokens) : length(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0) {}; Square& operator = (const Square&); void outputSquareCalculation(ostream&)const; }; class Rectangle { const double length; const double width; public: Rectangle(const vector  &tokens) : length(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0), width(tokens.size() > 2 ? atof(tokens[2].c_str()) : 0) {}; Rectangle& operator = (const Rectangle&); void outputRectangleCalculation(ostream&)const; }; class Triangle { const double length; public: Triangle(const vector  &tokens) : length(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0){}; Triangle& operator = (const Triangle&); void outputTriangleCalculation(ostream&)const; }; class Circle { const double radius; public: Circle(const vector  &tokens) : radius(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0) {}; Circle& operator = (const Circle&); void outputCircleCalculation(ostream&)const; }; class Cube { const double length; const double height; public: Cube(const vector  &tokens) : length(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0), height (tokens.size() > 2 ? atof(tokens[2].c_str()) : 0) {}; Cube& operator = (const Cube&); void outputCubeCalculation(ostream&)const; }; class Prism { const double length; const double height; public: Prism(const vector  &tokens) : length(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0), height(tokens.size() > 2 ? atof(tokens[2].c_str()) : 0) {}; Prism& operator = (const Prism&); void outputPrismCalculation(ostream&)const; }; class Cylinder { const double radius; const double height; public: Cylinder(const vector  &tokens) : radius(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0), height(tokens.size() > 2 ? atof(tokens[2].c_str()) : 0) {}; Cylinder& operator = (const Cylinder&); void outputCylinderCalculation(ostream&)const; }; class Box { const double length; const double width; const double height; public: Box(const vector  &tokens) : length(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0), width(tokens.size() > 1 ? atof(tokens[1].c_str()) : 0), height(tokens.size() > 2 ? atof(tokens[2].c_str()) : 0) {}; Box& operator = (const Box&); void outputBoxCalculation(ostream&)const; }; //Function Prototyes vector parseString(string); ostream& roundingTwo(ostream&); ostream& roundingOff(ostream&); int main() { //Declare Varaibles ifstream fin; ofstream fout; string line; //Open the input file fin.open("Shapes.input.txt"); fout.open("Shapes.output.txt"); vector myBag; //Create an empty bag vector myBagType; //It's companion Array while (!fin.eof()) { // Ignore the spaces getline(fin, line); int shape; vector tokens = parseString(line); if (tokens.size() == 0) continue; if (tokens.at(0) == "SQUARE") { shape = 1; Square* s = new Square(tokens); myBag.push_back(s); myBagType.push_back('S'); } else if (tokens.at(0) == "RECTANGLE") { Rectangle* r = new Rectangle(tokens); shape = 2; myBag.push_back(r); myBagType.push_back('R'); } else if (tokens.at(0) == "TRIANGLE") { Triangle* t = new Triangle(tokens); shape = 3; myBag.push_back(t); myBagType.push_back('T'); } else if (tokens.at(0) == "CUBE") { tokens.resize(4, "0"); Cube* c = new Cube(tokens); shape = 4; myBag.push_back(c); myBagType.push_back('C'); } else if (tokens.at(0) == "CIRCLE") { tokens.resize(3, "0"); Circle* e = new Circle(tokens); shape = 5; myBag.push_back(e); myBagType.push_back('E'); } else if (tokens.at(0) == "CYLINDER") { Cylinder* y = new Cylinder(tokens); shape = 6; myBag.push_back(y); myBagType.push_back('Y'); } else if (tokens.at(0) == "BOX") { Box* b = new Box(tokens); shape = 7; myBag.push_back(b); myBagType.push_back('B'); } else if (tokens.at(0) == "PRISM") { tokens.resize(4, "0"); shape = 8; Prism* pr = new Prism(tokens); myBag.push_back(pr); myBagType.push_back('P'); } else if (tokens.at(0) == "EOF") { shape = 9; continue; } else { cout << tokens.at(0) << " invalid object" << endl; } for (int i = 0; i <= tokens.size(); i++) { for (int j = i + 1; j < tokens.size(); j++) if (tokens[j] < tokens[i]) swap(tokens[i], tokens[j]); } } fin.close(); for (unsigned int i = 0; i < myBag.size(); i++) { if (myBagType[i] == 'S') { Square* pSquare = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Square& rSquare = *pSquare; //const_cast < vector&>(myBag).push_back(s); pSquare->outputSquareCalculation(cout); } else if (myBagType[i] == 'R') { Rectangle* pRectangle = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Rectangle& rRectangle = *pRectangle; pRectangle->outputRectangleCalculation(cout); } else if (myBagType[i] == 'T') { Triangle* pTriangle = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Triangle& rTriangle = *pTriangle; pTriangle->outputTriangleCalculation(cout); } else if (myBagType[i] == 'C') { Cube* pCube = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Cube& rCube = *pCube; pCube->outputCubeCalculation(cout); } else if (myBagType[i] == 'E') { Circle* pCircle = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Circle& rCircle = *pCircle; pCircle->outputCircleCalculation(cout); } else if (myBagType[i] == 'Y') { Cylinder* pCylinder = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Cylinder& rCylinder = *pCylinder; pCylinder->outputCylinderCalculation(cout); } else if (myBagType[i] == 'B') { Box* pBox = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Box& rBox = *pBox; pBox->outputBoxCalculation(cout); } else if (myBagType[i] == 'P') { Prism* pPrism = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Prism& rPrism = *pPrism; pPrism->outputPrismCalculation(cout); } } for (unsigned int i = 0; i < myBag.size(); i++) { if (myBagType[i] == 'S') { Square* pSquare = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Square& rSquare = *pSquare; pSquare->outputSquareCalculation(fout); } else if (myBagType[i] == 'R') { Rectangle* pRectangle = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Rectangle& rRectangle = *pRectangle; pRectangle->outputRectangleCalculation(fout); } else if (myBagType[i] == 'T') { Triangle* pTriangle = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Triangle& rTriangle = *pTriangle; pTriangle->outputTriangleCalculation(fout); } else if (myBagType[i] == 'C') { Cube* pCube = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Cube& rCube = *pCube; pCube->outputCubeCalculation(fout); } else if (myBagType[i] == 'E') { Circle* pCircle = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Circle& rCircle = *pCircle; pCircle->outputCircleCalculation(fout); } else if (myBagType[i] == 'Y') { Cylinder* pCylinder = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Cylinder& rCylinder = *pCylinder; pCylinder->outputCylinderCalculation(fout); } else if (myBagType[i] == 'B') { Box* pBox = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Box& rBox = *pBox; pBox->outputBoxCalculation(fout); } else if (myBagType[i] == 'P') { Prism* pPrism = reinterpret_cast(myBag[i]); // restore its "Movie-ness" Prism& rPrism = *pPrism; pPrism->outputPrismCalculation(fout); } } fout.close(); for (unsigned int i = 0; i < myBag.size(); i++) { if (myBagType[i] == 'S') { Square* s = reinterpret_cast(myBag[i]); // restore its "Movie-ness" delete s; // deallocate the Movie object at memory location myBag[i] } else if (myBagType[i] == 'R') { Rectangle* r = reinterpret_cast(myBag[i]); // restore its "Movie-ness" delete r; } else if (myBagType[i] == 'T') { Triangle* t = reinterpret_cast(myBag[i]); // restore its "Movie-ness" delete t; } else if (myBagType[i] == 'C') { Cube* c = reinterpret_cast(myBag[i]); // restore its "Movie-ness" delete c; } else if (myBagType[i] == 'I') { Circle* e = reinterpret_cast(myBag[i]); // restore its "Movie-ness" delete e; } else if (myBagType[i] == 'Y') { Cylinder* y = reinterpret_cast(myBag[i]); // restore its "Movie-ness" delete y; } else if (myBagType[i] == 'B') { Box* b = reinterpret_cast(myBag[i]); // restore its "Movie-ness" delete b; } else if (myBagType[i] == 'P') { Prism* p = reinterpret_cast(myBag[i]); // restore its "Movie-ness" delete p; } } system("PAUSE"); return 0; } vector parseString(string str) { stringstream s(str); istream_iterator begin(s), end; return vector(begin, end); } ostream& roundingTwo(ostream& out) { out.setf(ios::fixed); out.precision(2); // 2 decimal digits return out; } ostream& roundingOff(ostream& out) { out.unsetf(ios::fixed); out.precision(6); // the C++ default return out; } void Square::outputSquareCalculation(ostream& out) const { double area, length, perimeter; //Calculations area = this->length * this->length; perimeter = 4.0 * this->length; length = this->length; out << "SQUARE side = " << roundingOff << this->length << roundingTwo << " area = " << area << " perimeter = " << perimeter << endl; } void Rectangle::outputRectangleCalculation(ostream& out) const { double area, lenght, width, perimeter; //Calculations area = this->length * this->width; perimeter = (2.0 * this->length) + (2.0 * this->width); out << "RECTANGLE length = " << roundingOff << this->length << " width= " << this->width << roundingTwo << " area = " << area << " perimeter = " << perimeter << endl; } void Triangle::outputTriangleCalculation(ostream& out) const { double area, length, perimeter; //Calculations area = (1.732 * this->length *this->length) / 4.0; perimeter = 3.0 * this->length; out << "TRIANGLE side = " << roundingOff << this->length << roundingTwo << " area = " << area << " perimeter = " << perimeter << endl; } void Cube::outputCubeCalculation(ostream& out) const { double area, length, height, perimeter, volume; //Calculation area = 6 * this->length *this->length; volume = this->length * this->length * this->length; perimeter = (2.0 * this->length) + (2.0 * this->height); out << "CUBE side = " << roundingOff << this->length << roundingTwo << " area = " << area << " perimeter = " << perimeter << endl;; } void Circle::outputCircleCalculation(ostream& out) const { double area, radius, perimeter; //Calculations area = PI * this->radius * this->radius; perimeter = 2 * PI * this->radius; out << "CIRCLE radius = " << roundingOff << this->radius << roundingTwo << " area = " << area << " perimeter = " << perimeter << endl; } void Cylinder::outputCylinderCalculation(ostream& out) const { double area, radius, height, volume; //Calculations area = 2.0 * PI * this->radius * (this->radius + this->height); volume = PI * this->radius * this->radius * this->height; out << roundingOff << "CYLINDER radius = " << this->radius << " height = " << this->height << roundingTwo << " surface area = " << area << " volume = " << volume << endl; } void Box::outputBoxCalculation(ostream& out) const { double area, lenght, width, height, volume; //Calculations area = 2.0 * (this->length * this->width + this->length *this->height + this->width * this->height); volume = this->length * this->width * this->height; out << "BOX length = " << roundingOff << this->length << " widht = " << this->width << " height = " << this->height << roundingTwo << " surface area = " << area << " volume = " << volume << endl; } void Prism::outputPrismCalculation(ostream& out) const { double area, lenght, height, volume; //Calculations area = 3.0 * (this->length * this->height) + (1.732 * this->length * this->length) / 2.0; volume = (1.732 * this->length * this->length *this->height) / 4.0; out << "PRISM side = " << roundingOff << this->length << " height = " << this->height << roundingTwo << " surface area = " << area << " volume = " << volume << endl; } Square& Square::operator = (const Square& copyThis) { Square& host = *this; if (this!= ©This) { const_cast(host.length) = copyThis.length; } return host; } Rectangle& Rectangle::operator = (const Rectangle& copyThis) { Rectangle& host = *this; if (this != ©This) { const_cast(host.length) = copyThis.length; const_cast(host.width) = copyThis.width; } return host; } Triangle& Triangle::operator = (const Triangle& copyThis) { Triangle& host = *this; if (this != ©This) { const_cast(host.length) = copyThis.length; } return host; } Circle& Circle::operator = (const Circle& copyThis) { Circle& host = *this; if (this != ©This) { const_cast(host.radius) = copyThis.radius; } return host; } Cube& Cube::operator = (const Cube& copyThis) { Cube& host = *this; if (this != ©This) { const_cast(host.length) = copyThis.length; } return host; } Prism& Prism::operator = (const Prism& copyThis) { Prism& host = *this; if (this != ©This) { const_cast(host.length) = copyThis.length; const_cast(host.height) = copyThis.height; } return host; } Cylinder& Cylinder::operator = (const Cylinder& copyThis) { Cylinder& host = *this; if (this != ©This) { const_cast(host.radius) = copyThis.radius; const_cast(host.height) = copyThis.height; } return host; } Box& Box::operator = (const Box& copyThis) { Box& host = *this; if (this != ©This) { const_cast(host.length) = copyThis.length; const_cast(host.width) = copyThis.width; const_cast(host.height) = copyThis.height; } return host; } 

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

Recommended Textbook for

Financial management theory and practice

Authors: Eugene F. Brigham and Michael C. Ehrhardt

12th Edition

978-0030243998, 30243998, 324422695, 978-0324422696

Students also viewed these Programming questions