Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode

CRTP и двойной статическая полиморфизм C++

CRTP и двойной статическая полиморфизм

Ниже представлен паттерн проектирования на C++, известный как CRTP (Curiously Recurring Template Pattern).

С его помощью реализовать двойной статический полиморфизм. Пример ниже демонстрирует, как можно строить иерархии классов с использованием шаблонов для достижения поведения, похожего на виртуальные функции, но без накладных расходов раннего связывания.

Зачем нужен этот код?

Обычный полиморфизм в C++ реализуется через виртуальные функции и наследование, что приводит к использованию виртуальной таблицы (vtable) и некоторым накладным расходам. Однако иногда нам требуется полиморфизм без этих издержек, особенно если все типы известны на этапе компиляции. Здесь на помощь приходит CRTP — паттерн, при котором класс-наследник передаёт себя как параметр шаблона базовому классу.

В данном примере мы не просто реализуем классический CRTP, но и демонстрируем двойной статический полиморфизм: шаблонные базовые классы зависят сразу от двух параметров, что позволяет гибко комбинировать реализацию и интерфейс.

Что делает этот код?

  1. WordGetterBase — базовый шаблонный класс, реализующий интерфейс для получения строки (getWord()) и вывода её в консоль (printWord()). Реализация метода getWord() делегируется классу-наследнику через CRTP.
  2. WordGetterW1 и WordGetterW2 — конкретные реализации, возвращающие разные строки.
  3. StrPrinterBase — ещё один шаблонный базовый класс, который наследуется от конкретного WordGetter и расширяет интерфейс методом printStr(). Он также использует CRTP для вызова метода наследника.
  4. StrPrinter1 и StrPrinter2 — конкретные реализации принтера, которые форматируют и выводят строку, полученную от соответствующего WordGetter.
  5. В функции main демонстрируется использование этих классов: выводятся строки напрямую через WordGetter’ы и с помощью различных StrPrinter’ов.