Skip to content

Polymorphism

Polymorphism

Object Oriented programming (OOP) is a programming paradigm that relies on the concept of classes and objects. It is used to structure a software program into simple, reusable pieces of code blueprints (usually called classes), which are used to create individual instances of objects.

One of the key features of class inheritance is that a pointer to a derived class is type-compatible with a pointer to its base class. Polymorphism is the art of taking advantage of this simple but powerful and versatile feature.

1
2
class shape {
  public:

1
shape() : _side1(0), _side2(0) {}

1
explicit shape(double side) : _side1(side), _side2(side) {}

1
shape(double side1, double side2) : _side1(side1), _side2(side2) {}

1
virtual ~shape() = default;

1
virtual double area() { return 0; }

1
2
3
4
5
bool operator==(const shape &rhs) const {
    return _side1 == rhs._side1 && _side2 == rhs._side2;
}

bool operator!=(const shape &rhs) const { return !(rhs == *this); }

1
2
3
protected:
  double _side1;
  double _side2;

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class triangle : public shape {
  public:
    // Reuse base class constructors
    using shape::shape;

    // Default destructor
    ~triangle() override = default;

    // Override area member function
    double area() override { return this->_side1 * this->_side2 / 2; }
};

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class square : public shape {
  public:
    // Reuse base class constructors
    using shape::shape;

    // Default destructor
    ~square() override = default;

    // Override area member function
    double area() override { return this->_side1 * this->_side2; }
};

1
std::unique_ptr<shape> p = std::make_unique<square>(42);

1
2
3
4
5
6
7
8
std::vector<std::unique_ptr<shape>> v(30);
for (size_t i = 0; i < v.size(); ++i) {
    if (i % 2) {
        v[i] = std::make_unique<triangle>(i + 30);
    } else {
        v[i] = std::make_unique<square>(i + 30);
    }
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
for (std::unique_ptr<shape> &item : v) {
    if (dynamic_cast<triangle *>(item.get())) {
        std::cout << "This shape is a triangle\n";
    } else if (dynamic_cast<square *>(item.get())) {
        std::cout << "This shape is a square\n";
    } else if (dynamic_cast<shape *>(item.get())) {
        std::cout << "This is an abstract shape\n";
    }
    if (item && *item == *p) {
        std::cout << "It has the same area as p: " << item->area() << '\n';
    }
}

Share Snippets