// File: ex7-15a.cpp - Abstract classes and Polymorphism

#include <iostream>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;

const double pi = 3.141592654;

double drand();

class Shape
{
protected:
double x;
double y;
public:
Shape(double, double);
// pure virtual functions
virtual double area(void) const = 0;
virtual double girth(void) const = 0;
virtual string type() const = 0;
virtual ~Shape() {}
static const int NumShapeType = 3;

enum ShapeType
{
Square, Triangle, Circle
};
friend ostream& operator<<(ostream& out, const Shape& shape);
};

Shape::Shape(double c_x, double c_y) : x(c_x), y(c_y)
{
}

ostream& operator<<(ostream& out, const Shape& shape)
{
out << setprecision(2) << fixed;
out << shape.type() << " (" << shape.x << ',' << shape.y << ") ";
out << "area=" << shape.area() << " girth=" << shape.girth();
return out;
}

class Square : public Shape
{
private:
double side;
public:
Square(double c_x, double c_y, double s);
double area(void) const;
double girth(void) const;

string type() const
{
return "Square";
}
};

Square::Square(double c_x, double c_y, double s) : Shape(c_x, c_y), side(s)
{
}

double Square::area(void) const
{
return side * side;
}

double Square::girth(void) const
{
return 4. * side;
}

class Triangle : public Shape
{
private:
double a, b, c; // length of 3 sides
public:
Triangle(double c_x, double c_y, double s1, double s2, double s3);
double area(void) const;
double girth(void) const;

string type() const
{
return "Triangle";
}
};

Triangle::Triangle(double c_x, double c_y, double s1, double s2, double s3)
: Shape(c_x, c_y), a(s1), b(s2), c(s3)
{
}

double Triangle::area(void) const
{
double s = (a + b + c) / 2.; // semiperimeter
return sqrt(s * (s - a)*(s - b)*(s - c));
}

double Triangle::girth(void) const
{
return a + b + c;
}

class Circle : public Shape
{
private:
double radius;
public:
Circle(double c_x, double c_y, double r);
double area(void) const;
double girth(void) const;

string type() const
{
return "Circle";
}
};

Circle::Circle(double c_x, double c_y, double r) : Shape(c_x, c_y)
{
radius = r;
}

double Circle::area(void) const
{
return pi * radius*radius;
}

double Circle::girth(void) const
{
return 2. * pi*radius;
}

int main()
{
srand(time(0));
Shape* ptrShape;

// Create 10 shapes
for (int i = 0; i < 10; i++) {
Shape::ShapeType randomShape = static_cast<Shape::ShapeType> (rand() % Shape::NumShapeType);
switch (randomShape) {
case (Shape::Circle):
ptrShape = new Circle(drand(), drand(), drand());
break;
case (Shape::Square):
ptrShape = new Square(drand(), drand(), drand());
break;
case (Shape::Triangle):
ptrShape = new Triangle(drand(), drand(), drand(), drand(), drand());
break;
default:
;
}
cout << *ptrShape << endl;
delete ptrShape;
}
}

double drand()
{
return (rand() + 1.0) / (rand() / 10.0);
}



***** OUTPUT *****

Triangle (11.29,12.37) area=nan girth=27.49
Square (12.12,10.87) area=56.15 girth=29.97
Square (9.06,13.19) area=49.80 girth=28.23
Triangle (5.38,7.97) area=5.37 girth=15.11
Square (22.44,6.95) area=1844.48 girth=171.79
Circle (1.63,0.90) area=16.02 girth=14.19
Circle (57.05,0.42) area=467.19 girth=76.62
Square (12.33,5.10) area=5.44 girth=9.33
Square (3.97,96.71) area=143.86 girth=47.98
Triangle (6.31,1.05) area=17.93 girth=20.79

What does nan mean?