Наследование с CRTP - PullRequest
       15

Наследование с CRTP

1 голос
/ 24 февраля 2010

У меня есть эти 3 класса.

class A  
{  
    public:  
        virtual void Func() = 0;  
};

template<class T>  
class B : public A  
{  
    public:  
        void Func()  
        {  
            cout << "In B" << endl;  
            static_cast<T*>(this)->Func();  
        }  
};  

class C : public B<C>  
{  
    public:  
        void Func()  
        {  
            cout << "In C" << endl;  
        }  
};  

И я делаю это:

int main(int argc, char **argv)  
{  
    A *a = new C;  
    a->Func();  

    return 0;  
}  

И это печатает: «В С».

Если я сделаю это,

int main(int argc, char **argv)  
{  
    B<C> *a = new C;  
    a->Func();  

    return 0;  
}  

Он снова печатает "In C"

Что происходит?

Ответы [ 3 ]

1 голос
/ 24 февраля 2010

Func является виртуальным, a - указатель на экземпляр C, поэтому вызывается версия Func C.

1 голос
/ 24 февраля 2010

Вы вызываете виртуальную функцию-член объекта класса C, который перегружен этой функцией. Вызывает функцию в классе C.

Кроме того, это не CRTP, поскольку шаблонный класс B не наследуется от параметра шаблона класса.

0 голосов
/ 05 мая 2010

Код не завершен, добавьте #include и "using namespace std;". Что еще более важно, вы получаете желаемое поведение, удаляя объявление виртуальной функции в A. В общем, основная причина использования CRTP - сообщить шаблону тип, который он получает, и избегать виртуального вызова (или, лучше, избегать превращения метода в виртуальный).

template <typename T>
class ClassUsingSomething {
  public:
    void method1() {
      // I need to call method2, I do this by casting, so it doesn't need to be virtual.
      static_cast<T *>(this)->method2();
    }
};

class A: public ClassUsingSomething<A> {
  public:
    void method2() {
      //do something
    }
};
...