Какие виды полиморфизма поддерживаются в C++?

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

Ответ

В C++ полиморфизм — это возможность единого интерфейса работать с данными разных типов. Можно выделить следующие виды:

  1. Полиморфизм времени компиляции (Статический полиморфизм)

    • Перегрузка функций (Ad-hoc/Function Overloading): Несколько функций с одним именем, но разными типами или количеством параметров. Компилятор выбирает нужную на этапе компиляции.
      void print(int i) { std::cout << "int: " << i; }
      void print(double d) { std::cout << "double: " << d; }
      // Вызов: print(5); или print(3.14);
    • Параметрический полиморфизм (Шаблоны/Templates): Позволяет писать обобщённый код, работающий с любым типом, удовлетворяющим требованиям.
      template <typename T>
      T max(T a, T b) {
          return (a > b) ? a : b;
      }
      // Инстанцируется для int, double, пользовательских типов с operator>
  2. Полиморфизм времени выполнения (Динамический полиморфизм)

    • Полиморфизм подтипов (Наследование и виртуальные функции): Базовый класс определяет интерфейс (виртуальные функции), а производные классы предоставляют конкретные реализации. Выбор функции происходит во время выполнения на основе фактического типа объекта.
      class Shape {
      public:
          virtual void draw() const = 0; // Чисто виртуальная функция
          virtual ~Shape() = default;    // Виртуальный деструктор обязателен
      };
      class Circle : public Shape {
          void draw() const override { std::cout << "Drawing a circlen"; }
      };
      Shape* shape = new Circle();
      shape->draw(); // Вызовется Circle::draw() (динамическое связывание)
      delete shape;
  3. Приведение типов (Coercion) Неявное преобразование типов, выполняемое компилятором, например, из int в double в арифметических операциях. В C++ его роль менее значима по сравнению с языками со слабой типизацией.

Ключевое отличие: Статический полиморфизм (шаблоны) даёт максимальную производительность (нет накладных расходов на vtable), но может раздувать бинарный код. Динамический полиморфизм (виртуальные функции) обеспечивает гибкость и позднее связывание ценза небольших накладных расходов (указатель vptr, поиск в vtable).