Как в C++ реализуется полиморфизм?

«Как в C++ реализуется полиморфизм?» — вопрос из категории ООП, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В C++ полиморфизм времени выполнения реализуется через виртуальные функции и наследование. Механизм основан на таблице виртуальных функций (vtable) и указателе на нее (vptr) в каждом объекте полиморфного класса.

Базовый пример:

#include <iostream>

class Shape {
public:
    // Виртуальная функция обеспечивает динамическое связывание
    virtual void draw() const {
        std::cout << "Drawing a generic shape.n";
    }
    // Виртуальный деструктор КРИТИЧЕН для корректного удаления объектов через указатель на базовый класс
    virtual ~Shape() = default;
};

class Circle : public Shape {
public:
    // Ключевое слово 'override' явно указывает на переопределение (проверяется компилятором)
    void draw() const override {
        std::cout << "Drawing a circle.n";
    }
};

class Square : public Shape {
public:
    void draw() const override {
        std::cout << "Drawing a square.n";
    }
};

int main() {
    Shape* shapes[] = {new Circle(), new Square()};

    for (Shape* s : shapes) {
        s->draw(); // Вызовется правильная версия draw() для каждого типа
        delete s;  // Корректное удаление благодаря виртуальному деструктору
    }
    return 0;
}

Ключевые элементы:

  1. virtual в базовом классе: помечает функцию как переопределяемую.
  2. override (C++11) в производном классе: гарантирует, что функция переопределяет виртуальную функцию базового класса.
  3. Виртуальный деструктор: Обязателен, если возможна работа с объектами через указатель на базовый класс и их удаление.
  4. Чисто виртуальные функции и абстрактные классы: virtual void draw() const = 0; делает класс Shape абстрактным, его нельзя инстанцировать.

Полиморфизм работает только при вызове через указатель или ссылку на базовый класс.