Skip to content
UniCircle
EasyCodingPolymorphism and virtual functions

Shape areas with an abstract base class and virtual functions

Question CPP-OOP-103

Model shapes with an abstract base class Shape that has a pure virtual double area() const and a virtual std::string name() const. Derive Circle, Rectangle, Square and Triangle from it.

Read n shapes into a std::vector<std::unique_ptr<Shape>>. Print each shape's name and area, then the total area. Print every number with exactly 2 digits after the decimal point.

  • Use π = 3.141592653589793.
  • For a triangle with sides a, b, c, use Heron's formula: s = (a + b + c) / 2 and area = √(s(s − a)(s − b)(s − c)).

Constraints

  • 1 ≤ n ≤ 1000
  • 1 ≤ every dimension ≤ 1000

Input and output

Input
First line: n. Then n lines, each one of: `circle r`, `rectangle w h`, `square s`, `triangle a b c` (positive integers; triangles are valid).
Output
n lines `name area`, then one line `total X`.

Examples

Input 1

4
circle 1
rectangle 3 4
square 5
triangle 3 4 5

Output

circle 3.14
rectangle 12.00
square 25.00
triangle 6.00
total 46.14

π × 1² = 3.14, 12, 25, and the 3-4-5 right triangle has area 6. Total: 46.14.

Input 2

2
circle 10
triangle 2 2 3

Output

circle 314.16
triangle 1.98
total 316.14

Heron: s = 3.5, area = √(3.5 × 1.5 × 1.5 × 0.5) ≈ 1.98.

Show hints
  • virtual double area() const = 0; makes the class abstract, so it cannot be instantiated.
  • Give the base class a virtual destructor, because you delete derived objects through base pointers.
  • std::make_unique<Circle>(r) creates the object; the vector owns it.
Show the explanation

Design

C++
struct Shape {
    virtual ~Shape() = default;              // needed: we delete through Shape*
    virtual double area() const = 0;         // pure virtual makes Shape abstract
    virtual std::string name() const = 0;
};
struct Circle : Shape {
    double r;
    explicit Circle(double r) : r(r) {}
    double area() const override { return PI * r * r; }
    std::string name() const override { return "circle"; }
};

Square can derive from Rectangle and call Rectangle(s, s), overriding only name().

Why it works. A call such as p->area() through a Shape* or unique_ptr<Shape> is dispatched at run time to the derived class's override, using the object's vtable. The printing loop never needs an if (type == ...) chain. Adding a new shape means adding a new class, with no change to existing code. This is the open/closed principle.

Points interviewers check

  • override makes the compiler confirm that you really override a base function. A typo in the signature then becomes a compile error.
  • Without the virtual destructor, delete through a base pointer is undefined behaviour, and derived members are not destroyed.
  • unique_ptr frees every shape automatically when the vector goes out of scope (RAII), so there is no manual delete.
  • A vector of Shape objects (by value) cannot hold derived objects. Copying a Circle into a Shape would slice it. Polymorphism needs pointers or references.

Output: use fixed << setprecision(2) or printf("%.2f"). Add the areas in input order to get the total.

Original UniCircle question. Last reviewed 22 Oct 2026.