Как стать автором
Обновить

Комментарии 12

Смысл примера не понятен. В чем преимущество перед обычным наследованием?

код
#include <iostream>

using namespace std;

class Vehicle {
public:
    virtual int geNumberOfWheels() const = 0;
};

class Bicycle: public Vehicle {
public:
    virtual int geNumberOfWheels() const override {
        return 2;
    }
};

class Car: public Vehicle {
public:
    virtual int geNumberOfWheels() const override {
        return 4;
    }
};

int main()
{
    Vehicle *one = new Car();
    Vehicle *another = new Bicycle();
    cout << one->geNumberOfWheels() << endl;
    cout << another->geNumberOfWheels() << endl;
    return 0;
}

В статическом полиморфизме.

Преимущества начинаются, когда у наследников есть полиморфные

  • статические члены: обычными виртуальными функциями их уже не пробросить, нужен механизм словарей/фабрик (в шарпе и яве это сделано на дженериках - ну или ручками, ручками всё)

  • свойства времени компиляции: типы, константы и всё такое - тут уже даже дженерики не спасут

template<class Impl> class Vehicle {
  // пример статической функции
  static Impl* create_road_train() {
    if (!Impl::can_tow() || !Impl::can_be_towed()) return nullptr;
    Impl* tow = Impl::create();
    Impl* trailer = Impl::create();
    return Impl::bind(tow, trailer);
    // или, может быть
    return tow->bind(trailer);
  }

  // пример свойств времени компиляции
  Impl::WheelType wheels_[Impl::number_of_wheels];
};

Можно в копилку докинуть возможность запилить частичный интерфейс: базовый класс может детектировать наличие опциональных функций у наследников и вызывать их только если они есть. И всё это проверится статически

Impl::WheelType wheels_[Impl::number_of_wheels];

Прямо вот так оно работать не будет, Impl -то неполный в этот момент.

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

Призываю @Kelbonнакинуть : )

что тут писать ,это же блог компании отус, итак всё ясно

Ору.

Я такую штуку делал, когда создавал шаблон для описания графа с вершинами и ребрами. Но я не знал, что это так называется.

Такую штуку делали в каком-то очень дремучем году, например, Microsoft ATL/WTL.

Такую штуку кто только ни делал, собственно, название паттерна так и возникло: автор статьи, в которой паттерн был формализован, отметил, что этот паттерн (pattern), основанный на хитром использовании шаблонов (template), является удивительно (curiously) часто повторяющимся (recurring) от кодовой базы к кодовой базе, причем эти кодовые базы зачастую никак не связаны друг с другом. То есть имя паттерна никак не связано с механизмом его реализации, хотя из статьи в статью кочуют попытки расшифровку аббревиатуры притянуть (причем за уши) к реализации. Даже удивительно, что в этой статье это притягивание не возникло, но я думаю, это от небрежности, а не от благого намерения.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий