// File: ass2.cpp - CIS29 - Assignment 2 Solution
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cmath> // for sqrt()
using namespace std;
const double PI = 3.141592654;
class Solid
{
public:
Solid() {}
virtual double volume() const = 0;
virtual double surfaceArea() const = 0;
virtual const char* const name() const = 0;
};
class Rectangular : public Solid
{
public:
Rectangular(double length = 0, double width = 0, double height = 0);
double volume() const;
double surfaceArea() const;
virtual const char* const name() const = 0;
protected:
double length_;
double width_;
double height_;
};
Rectangular::Rectangular(double length, double width, double height)
:length_(length), width_(width), height_(height)
{
}
double Rectangular::volume() const
{
return length_ * width_ * height_;
}
double Rectangular::surfaceArea() const
{
return 2*(length_ * width_ + length_ * height_ + width_ * height_);
}
class RectangularPrism : public Rectangular
{
public:
RectangularPrism(double length = 0, double width = 0, double height = 0);
const char* const name() const { return "rectangular prism"; }
};
RectangularPrism::RectangularPrism(double length, double width, double height)
: Rectangular(length, width, height)
{}
class Cube : public RectangularPrism
{
public:
Cube(double s = 0)
: RectangularPrism(s,s,s) {}
const char* const name() const { return "cube"; }
};
class Circular : public Solid
{
public:
Circular(double radius = 0);
double radius() const;
virtual double volume() const = 0;
virtual double surfaceArea() const = 0;
virtual const char* const name() const = 0;
protected:
double radius_;
};
Circular::Circular(double radius)
: radius_(radius)
{}
double Circular::radius() const
{
return radius_;
}
class Sphere : public Circular
{
public:
Sphere(double radius = 0);
double volume() const;
double surfaceArea() const;
const char* const name() const;
};
Sphere::Sphere(double radius)
: Circular(radius)
{}
double Sphere::volume() const
{
return 4./3. * PI * radius_ * radius_ * radius_;
}
double Sphere::surfaceArea() const
{
return 4. * PI * radius_ * radius_;
}
const char* const Sphere::name() const
{
return "sphere";
}
class Cylinder : public Circular
{
protected:
double height_;
public:
Cylinder(double radius = 0, double height = 0);
double volume() const;
double surfaceArea() const;
const char* const name() const;
};
Cylinder::Cylinder(double radius, double height)
: Circular(radius), height_(height)
{}
double Cylinder::volume() const
{
return PI * radius_ * radius_ * height_;
}
double Cylinder::surfaceArea() const
{
return 2. * PI * radius_ * (height_ + radius_);
}
const char* const Cylinder::name() const
{
return "cylinder";
}
int main()
{
double d1, d2, d3;
char code[3];
ifstream fin("/deanza/data/ass2data");
if (!fin) {
cerr << "Unable to open /deanza/data/ass2data\n";
exit(-2);
}
Solid* ptrSolid;
cout << fixed << setprecision(4);
for (unsigned i = 0; i< 50; ++i) {
fin >> code;
if (!fin) {
break;
}
if (!strcmp(code,"cy")) {
fin >> d1 >> d2;
ptrSolid = new Cylinder(d1,d2);
}
else if (!strcmp(code,"sp")) {
fin >> d1;
ptrSolid = new Sphere(d1);
}
else if (!strcmp(code,"re")) {
fin >> d1 >> d2 >> d3;
ptrSolid = new RectangularPrism(d1,d2,d3);
}
else if (!strcmp(code,"cu")) {
fin >> d1;
ptrSolid = new Cube(d1);
}
else {
cout << "************* " << code[0]<< code[1] << endl;
continue;
}
cout << left << setw(18) << ptrSolid->name() << right << setw(15);
if (ptrSolid->surfaceArea()>10000.) {
cout << scientific << setprecision(2) << ptrSolid->surfaceArea();
}
else {
cout << fixed << setprecision(4) << ptrSolid->surfaceArea();
}
if (ptrSolid->volume()>10000.) {
cout << setw(15) << scientific << setprecision(2) << ptrSolid->volume();
}
else {
cout << setw(15) << fixed << setprecision(4) << ptrSolid->volume();
}
cout << endl;
delete ptrSolid;
}
fin.close();
system("pause");
return 0;
}