Exercise 8:

Create a directory ex8 and store in this directory all the files corresponding to this exercise.

Question 1: virtual functions and ABC (50 points).

This first question will exercise your understanding of dynamic polymorphism, virtual functions and abstract base classes. You have to write three classes Rectangle, Circle and Ellipse that implement a common interface Shape_2d.

Consider the interface (or abstract base class) Shape_2d. This interface has two methods used to retrieve the name of the shape and compute its area:

An header with the definition of the interface Shape_2d is given below. Please type it in a file named "Shape_2d.h":
// Shape_2d.h

#include <string>

#ifndef SHAPE_2D_H
#define SHAPE_2D_H

class Shape_2d {
public:
 virtual std::string get_name() const = 0;
 virtual double compute_area() const = 0;

 virtual ~Shape_2d() {}
};

#endif // SHAPE_2D_H
Shape_2d is an abstract base class (or an interface) since it has virtual methods. Objects of type Shape_2d can not be created.

Your goal is to implement the classes: Rectangle, Circle and Ellipse. These classes implement the interface Shape_2d.

The constructor for Rectangle is: The constructor for Circle is: The constructor for Ellispe is: All the quantities above have type double (or array of double).

Please create the files: "Rectangle.h", "Rectangle.cpp", "Circle.h", "Circle.cpp", "Ellipse.h" and "Ellipse.cpp". Header files will contain the classes definition. The code for the methods as well as the constructors (and destructor) should go in the .cpp files.

To test your code, please type (and use) the following code in a file "test_shape.cpp"
#include <iostream>
#include <string>
#include "Shape_2d.h"
#include "Circle.h"
#include "Ellipse.h"
#include "Rectangle.h"

void compute_and_print_area(Shape_2d* s)
{
  std::cout << "Area of " << s->get_name() << ": " << std::endl;
  std::cout <<  s->compute_area() << std::endl;
}

int main()
{
 double center[2] = {0.0, 0.0};
 Circle* c = new Circle(center, 1.0);
 Rectangle* r = new Rectangle(center, 10.0, 5.0);
 Ellipse* e = new Ellipse(center, 2.0, 1.0);

 compute_and_print_area(c);
 compute_and_print_area(r);
 compute_and_print_area(e);

 delete c;
 delete r;
 delete e;
}

Question 2: Adding polygons (50 points).

In addition to rectangles, circles and ellipses, we want to handle polygons. A polygon is the area enclosed by a closed curve made of linear segments (see picture).

A polygon is constructed from an integer "n" (the number of points) and a list of 2d points "Pi = (xi,yi)". We use the convention that Pn = P0 in order to have a closed loop of segments. The area for a polygon is given by the formula: 2 * Area = Sum_{i=0}^{n-1} x_i y_{i+1} - y_i x_i{i+1}.

Please create the files: "Polygon.h" and "Polygon.cpp". Type the following code in "Polygon.h":

// Polygon.h
#include <string>
#include "Shape_2d.h"

#ifndef POLYGON_H
#define POLYGON_H

class Polygon : public Shape_2d {
public:
 Polygon(int n, double* xi, double* yi);
 Polygon(const Polygon& p);
 ~Polygon();
 
 Polygon& operator= (const Polygon& p);
 virtual double compute_area() const;
 virtual std::string get_name() const;

private:
 int num_points;
 double* x_;
 double* y_;
};

#endif // POLYGON_H
In the file "Polygon.cpp", type and complete the following code:
#include "Polygon.h"

Polygon::Polygon(int n, double* xi, double* yi) 
     : num_points(n), x_(new double[n]), y_(new double[n])
{
  for (int i = 0; i < num_points; i++)
  {
    x_[i] = xi[i];
    y_[i] = yi[i];
  }
}

// Write below the code for: the copy constructor, 
// the destructor, the assignment operator
// compute_area and get_name.
// .....
To test your code please modify the file "test_shape.cpp" from the question 1 as follow (only the lines delimited by comments: new code, need to be added):

#include <iostream>
#include <string>
#include "Shape_2d.h"
#include "Circle.h"
#include "Ellipse.h"
#include "Rectangle.h"

// new code for testing Polygon:
#include "Polygon.h"

void compute_and_print_area(Shape_2d* s)
{
  std::cout << "Area of " << s->get_name() << ": " << std::endl;
  std::cout <<  s->compute_area() << std::endl;
}

int main()
{
 double center[2] = {0.0, 0.0};
 Circle* c = new Circle(center, 0.0);
 Rectangle* r = new Rectangle(center, 10.0, 5.0);
 Ellipse* e = new Ellipse(center, 2.0, 1.0);

 // new code for testing Polygon:
 int n = 4;
 double x[4] = {5.0, 5.0, -5.0, -5.0};
 double y[4] = {-2.5, 2.5, 2.5, -2.5};
 Polygon* p = new Polygon(n, x, y);
 // end new code

 compute_and_print_area(c);
 compute_and_print_area(r);
 compute_and_print_area(e);

 // new code for testing Polygon:
 compute_and_print_area(p);
 // end new code

 delete c;
 delete r;
 delete e;

 // new code for testing Polygon:
 delete p;
 // end new code
}