Curiously recurring template pattern

      Комментарии к записи Curiously recurring template pattern отключены

Помечено: , , ,

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 2 мес., 3 нед. назад.

  • Автор
    Сообщения
  • #3619

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

    #include <iostream>
    #include <memory>
    
    class abstract
    {
    public:
    
        virtual ~abstract() {}
    
        virtual void hello() = 0;
    };
    
    template <class T>
    class base : public abstract
    {
    public:
    
        virtual void hello()
        {
            static_cast<T*>(this)->do_hello();
        }
    
    private:
    
        void do_hello()
        {
            std::cout << "base::hello()" << std::endl;
        }
    };
    
    class left : public base<left>
    {
    public:
    
        void do_hello()
        {
            std::cout << "left::hello()" << std::endl;
        }
    };
    
    class right : public base<right>
    {
    
    };
    
    int main()
    {
        typedef std::auto_ptr<abstract> abstract_ptr;
    
        abstract_ptr a1(new left);
        abstract_ptr a2(new right);
    
        a1->hello();
        a2->hello();
    
        return 0;
    }

    Данный паттерн имеет некоторые интересные свойства. Во-первых, он позволяет родительскому классу знать о дочернем на правах forward declaration, при этом никаких преобразований типов для этого делать не нужно. Во-вторых, он позволяет совершенно безопасно делать приведение вниз по иерархии обычным static_cast. В третьих, он позволяет реализовывать так называемые статические виртуальные функции (пример вызова такой функции находится в строке 19).

    «CRTP» имеет более сложную организацию, чем «Nonvirtual interface», поэтому, выбирая между последними, следует четко понимать возможности паттернов и ваши потребности — соответствуют ли они друг другу.

Для ответа в этой теме необходимо авторизоваться.