#include <iostream>
#include <vector>
#include <memory>
#include <numbers>   // C++20: std::numbers::pi; if your compiler does not support it, replace it with a constant

// Abstract base class: open for extension (can be derived arbitrarily) and closed for modification (interface is fixed)
class Shape {
public:
    virtual double area() const = 0;
    virtual ~Shape() = default;
};

// Concrete shape: circle
class Circle : public Shape {
public:
    explicit Circle(double radius) : radius_(radius) {}
    double area() const override {
        return std::numbers::pi * radius_ * radius_;
    }
private:
    double radius_;
};

// Concrete shape: rectangle
class Rectangle : public Shape {
public:
    Rectangle(double width, double height) : width_(width), height_(height) {}
    double area() const override {
        return width_ * height_;
    }
private:
    double width_, height_;
};

// Concrete shape: triangle (new type; just derive from Shape and the rest of the code stays unchanged)
class Triangle : public Shape {
public:
    Triangle(double base, double height) : base_(base), height_(height) {}
    double area() const override {
        return 0.5 * base_ * height_;
    }
private:
    double base_, height_;
};

// Client code: depends on the abstract Shape, not on concrete types — satisfies the open/closed principle
double CalculateTotalArea(const std::vector<std::unique_ptr<Shape>>& shapes) {
    double total = 0.0;
    for (const auto& shape : shapes) {
        total += shape->area();
    }
    return total;
}

int main() {
    // Create different shape types
    std::vector<std::unique_ptr<Shape>> shapes;
    shapes.push_back(std::make_unique<Circle>(5.0));
    shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));
    shapes.push_back(std::make_unique<Triangle>(3.0, 4.0));  // New triangle

    // Print the area of each shape
    std::cout << "Areas of individual shapes:\n";
    for (const auto& shape : shapes) {
        std::cout << shape->area() << '\n';
    }

    // Calculate the total area — CalculateTotalArea can handle new shapes without any modification
    double total = CalculateTotalArea(shapes);
    std::cout << "Total area: " << total << std::endl;

    return 0;
}

results matching ""

    No results matching ""