C++: Shapes through a base pointer

Read n shapes into a vector<Shape*>, where Shape is an abstract class with a virtual area(). Then print each area and the total, all with two decimals. Use 3.14159 for pi.

What to build

A list of shapes handled through pointers to an abstract base class.

Requirements

  • Give Shape a pure virtual area() and a virtual destructor.
  • Store each shape as a Shape* in a vector.
  • Print the areas and the total with two decimals, and delete every shape.

Input

The first line has n (1 ≤ n ≤ 100). Each of the next n lines is circle r or rect w h (decimal numbers from 0 to 1000).

Output

n lines with the areas, then total T; every number with exactly two decimals.

Constraints

1 ≤ n ≤ 100, and the sizes are from 0 to 1000.

Example

Input:

2
circle 1
rect 2 3

Output:

3.14
6.00
total 9.14

Why it works

Because area() is virtual, the loop calls the right version for each real shape without knowing which kind it is.

Examples

Example 1 · Input
2
circle 1
rect 2 3
Expected output
3.14
6.00
total 9.14
Example 2 · Input
1
rect 0.5 0.5
Expected output
0.25
total 0.25

Hints

Hint 1

Shape has virtual double area() const = 0; and a virtual destructor.

Hint 2

Circle and Rect override area(). Store new Circle(r) or new Rect(w, h) in a vector<Shape*>.

Hint 3

Print with cout << fixed << setprecision(2); and delete the shapes at the end.

Solution

Show one correct solution (try it yourself first)
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;

class Shape {
public:
    virtual double area() const = 0;
    virtual ~Shape() {}
};

class Circle : public Shape {
    double r;
public:
    Circle(double r) : r(r) {}
    double area() const override { return 3.14159 * r * r; }
};

class Rect : public Shape {
    double w, h;
public:
    Rect(double w, double h) : w(w), h(h) {}
    double area() const override { return w * h; }
};

int main() {
    int n;
    cin >> n;
    vector<Shape*> shapes;
    for (int i = 0; i < n; i++) {
        string kind;
        cin >> kind;
        if (kind == "circle") {
            double r;
            cin >> r;
            shapes.push_back(new Circle(r));
        } else {
            double w, h;
            cin >> w >> h;
            shapes.push_back(new Rect(w, h));
        }
    }
    cout << fixed << setprecision(2);
    double total = 0;
    for (Shape* s : shapes) {
        cout << s->area() << endl;
        total += s->area();
    }
    cout << "total " << total << endl;
    for (Shape* s : shapes) delete s;
    return 0;
}

Lesson: Virtual functions and polymorphism →