Re[3]: модификация интерфейса в compile time
От: Кодт Россия  
Дата: 08.01.09 11:34
Оценка: 1 (1)
Здравствуйте, mjau, Вы писали:

M>Ааээ а чем это отличается от просто виртуальных функций? В наследниках тоже будут свои реализации foo() и bar() и их тоже надо будет ифдефить. На оставленные без деклараций тела компилятор будет ругаться. В чем выигрыш?


Отличается тем, что, допустим, тебе эти foo(), bar() для чего-то ещё нужны, сами по себе.
И заодно, через них выражается реализация B().
Выигрыш в том, что B() ты убираешь малой кровью.

К>>// а эта на CRTP


M>А CRTP работает дальше одного наследника? А как?


У классов с виртуальными функциями в рантайме в объекте хранится vfptr на актуальную vtbl, а у CRTP — в шаблон класса протаскивается параметр — финальный класс.
Единственная сложность — это то, что нефинальные классы должны быть шаблонами.
template<class TActual>
class Base
{
public:
    TActual      & self()       { return *static_cast<TActual      *>(this); }
    TActual const& self() const { return *static_cast<TActual const*>(this); }
    
    // паттерн Шаблонный Метод: "виртуально" вызываем методы наследника
    void foo()
    {
        self().bar();
        self().buz();
    }
    
    void bar() {} // "виртуальная" функция, которую наследник может переопределить, перегрузив
    //void buz(); // "чисто виртуальная" функция - наследник обязан её определить
};

template<class TActual>
class Intermediate : public Base<TActual>
{
    void bar() {}
    void buz() {}
};

class Final : public Intermediate<Final>
{
    void bar() {}
};


CRTP вовсю используется в ATL и WTL. Причём используется довольно стройно и последовательно. Так что можешь познакомиться с этой идиомой практически.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.