C++: An abstract shape with two measurements

An abstract class lists what every shape must be able to do, and leaves the how to each shape.

What to build

An abstract Shape class with Rect and Square classes that complete it.

Requirements

  • Give Shape two pure virtual functions, area() and perimeter(), and a virtual destructor.
  • Give Shape an ordinary member function report() that prints both values.
  • Override both functions in Rect and in Square.

Input

The first line has q. Each of the next q lines is rect W H or square S.

Output

One line per shape: area A perimeter P.

Constraints

1 ≤ q ≤ 100, and every length is from 0 to 1000.

Example

Input:

2
rect 3 4
square 5

Output:

area 12 perimeter 14
area 25 perimeter 20

Why it works

report() is written once in the abstract class, and each concrete class fills in the two missing pieces. A Shape itself can never be created, because it has no area of its own.

Examples

Example 1 · Input
2
rect 3 4
square 5
Expected output
area 12 perimeter 14
area 25 perimeter 20
Example 2 · Input
1
square 1
Expected output
area 1 perimeter 4

Hints

Hint 1

Declare `virtual int area() const = 0;` and `virtual int perimeter() const = 0;` in `Shape`.

Hint 2

`report()` can be an ordinary member function of `Shape` that calls the two pure virtual functions.

Solution

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

class Shape {
public:
    virtual ~Shape() {}
    virtual int area() const = 0;
    virtual int perimeter() const = 0;
    void report() const {
        cout << "area " << area() << " perimeter " << perimeter() << endl;
    }
};

class Rect : public Shape {
    int w, h;
public:
    Rect(int w, int h) : w(w), h(h) {}
    int area() const override { return w * h; }
    int perimeter() const override { return 2 * (w + h); }
};

class Square : public Shape {
    int s;
public:
    Square(int s) : s(s) {}
    int area() const override { return s * s; }
    int perimeter() const override { return 4 * s; }
};

int main() {
    int q;
    cin >> q;
    while (q-- > 0) {
        string kind;
        cin >> kind;
        if (kind == "rect") {
            int w, h;
            cin >> w >> h;
            Rect r(w, h);
            r.report();
        } else {
            int s;
            cin >> s;
            Square sq(s);
            sq.report();
        }
    }
    return 0;
}

Lesson: Abstract classes and interfaces →