CRTP и двойной статическая полиморфизм C++
Ниже представлен паттерн проектирования на C++, известный как CRTP (Curiously Recurring Template Pattern).
С его помощью реализовать двойной статический полиморфизм. Пример ниже демонстрирует, как можно строить иерархии классов с использованием шаблонов для достижения поведения, похожего на виртуальные функции, но без накладных расходов раннего связывания.
Обычный полиморфизм в C++ реализуется через виртуальные функции и наследование, что приводит к использованию виртуальной таблицы (vtable) и некоторым накладным расходам. Однако иногда нам требуется полиморфизм без этих издержек, особенно если все типы известны на этапе компиляции. Здесь на помощь приходит CRTP — паттерн, при котором класс-наследник передаёт себя как параметр шаблона базовому классу.
В данном примере мы не просто реализуем классический CRTP, но и демонстрируем двойной статический полиморфизм: шаблонные базовые классы зависят сразу от двух параметров, что позволяет гибко комбинировать реализацию и интерфейс.
- WordGetterBase — базовый шаблонный класс, реализующий интерфейс для получения строки (
getWord()
) и вывода её в консоль (printWord()
). Реализация методаgetWord()
делегируется классу-наследнику через CRTP. - WordGetterW1 и WordGetterW2 — конкретные реализации, возвращающие разные строки.
- StrPrinterBase — ещё один шаблонный базовый класс, который наследуется от конкретного WordGetter и расширяет интерфейс методом
printStr()
. Он также использует CRTP для вызова метода наследника. - StrPrinter1 и StrPrinter2 — конкретные реализации принтера, которые форматируют и выводят строку, полученную от соответствующего WordGetter.
- В функции
main
демонстрируется использование этих классов: выводятся строки напрямую через WordGetter’ы и с помощью различных StrPrinter’ов.