2011-12-15 2 views
18

В CRTP pattern у нас возникают проблемы, если мы хотим сохранить функцию реализации в производном классе как защищенную. Мы должны либо объявить базовый класс, как друг производного класса, либо использовать something like this (я не пробовал метод в связанной статье). Есть ли другой (простой) способ, который позволяет сохранить функцию реализации в производном классе как защищенную?CRTP с защищенным производным членом

Edit: Вот простой пример кода:

template<class D> 
class C { 
public: 
    void base_foo() 
    { 
     static_cast<D*>(this)->foo(); 
    } 
}; 


class D: public C<D> { 
protected: //ERROR! 
    void foo() { 
    } 
}; 

int main() { 
    D d; 
    d.base_foo(); 
    return 0; 
} 

Приведенный выше код дает error: ‘void D::foo()’ is protected с г ++ 4.5.1, но компилирует если protected заменяется public.

+0

Не это то, что виртуальные функции для? –

+2

@BoPersson, виртуальные функции предназначены для полиморфизма во время выполнения, CRTP предназначен для полиморфизма времени компиляции. В мире есть место для обоих. См. Http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern –

+0

@Mark. Конечно, есть, но если требование - вызвать защищенную функцию в производном классе, виртуальные машины выглядят как подходящие. :-) –

ответ

21

Это не проблема вообще, и решается с одной линией, в производном классе:

friend class Base<Derived>;

#include <iostream> 

template< typename PDerived > 
class TBase 
{ 
public: 
    void Foo(void) 
    { 
    static_cast< PDerived* > (this)->Bar(); 
    } 
}; 

class TDerived : public TBase<TDerived> 
{ 
    friend class TBase<TDerived> ; 
protected: 
    void Bar(void) 
    { 
    std::cout << "in Bar" << std::endl; 
    } 
}; 

int main(void) 
{ 
TDerived lD; 

lD.Foo(); 

return (0); 
} 
Смежные вопросы