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 5Output
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 3Output
circle 314.16
triangle 1.98
total 316.14Heron: 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
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
overridemakes the compiler confirm that you really override a base function. A typo in the signature then becomes a compile error.- Without the virtual destructor,
deletethrough a base pointer is undefined behaviour, and derived members are not destroyed. unique_ptrfrees every shape automatically when the vector goes out of scope (RAII), so there is no manualdelete.- A vector of
Shapeobjects (by value) cannot hold derived objects. Copying aCircleinto aShapewould 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.
