Middle+
169
C++ da statik polimorfizm idiomasi qanday nomlanadi?
AIdan javob
sobes.tech AI
Curiously Recurring Template Pattern (CRTP), также известна как статичеcкий полиморфизм или полиморфизм времени компиляции.
Принцип CRTP основывается на том, что шаблонный класс Base использует в качестве шаблонного параметра сам себя, будучи при этом базовым классом для некоторого производного класса Derived.
template <typename T>
class Base
{
public:
void interfaceMethod()
{
// Статический вызов метода 'implementationMethod'
// на объекте типа Derived (который является T)
static_cast<T*>(this)->implementationMethod();
}
// Виртуальный метод здесь не нужен
};
class Derived : public Base<Derived>
{
public:
void implementationMethod()
{
// Реализация специфичная для Derived
// ...
}
};
Преимущества CRTP перед динамическим полиморфизмом (с виртуальными функциями):
- Производительность: Вызовы функций являются статическими и разрешаются во время компиляции, избегая накладных расходов виртуальной таблицы.
- Отсутствие накладных расходов на виртуальные функции: Нет необходимости хранить и использовать vptr/vtbl.
- Более строгая типизация: Ошибки, связанные с несоответствием типов или отсутствием реализации, обнаруживаются на этапе компиляции.
Недостатки:
- Необходимость знатть тип потомка: Base-класс должен быть шаблонным и "знать" тип производного класса.
- Сложность для новичков: Паттерн может быть менее интуитивно понятен по сравнению с классическим наследованием с виртуальными функциями.
- Невозможность работать с коллекцией разных CRTP-типов: Нельзя хранить в одном контейнере объекты разных производных CRTP-классов и вызывать их через базовое указание/ссылку.
Сравнение с динамическим полиморфизмом:
| Аспект | CRTP (статический полиморфизм) | Динамический полиморфизм (виртуальные функции) |
|---|---|---|
| Разрешение вызова | Время компиляции | Время выполнения |
| Производительность | Выше (нет накладных расходов vtbl) | Ниже (есть накладные расходы vtbl) |
| Накладные расходы | Нет vptr/vtbl | Есть vptr/vtbl |
| Гибкость (коллекции) | Нет (нельзя работать с разнородными типами через общий базовый указатель/ссылку) | Да (можно работать с разнородными типами) |
| Обнаружение ошибок | Время компиляции | Время выполнения |
| Сложность | Выше для новичков | Ниже для новичков |