2011-12-15 14 views
18

Nel CRTP pattern, ci imbattiamo in problemi se vogliamo mantenere la funzione di implementazione nella classe derivata come protetta. Dobbiamo dichiarare la classe base come un amico della classe derivata o usare something like this (non ho provato il metodo nell'articolo collegato). C'è un altro (semplice) modo che consente di mantenere la funzione di implementazione nella classe derivata come protetta?CRTP con membro derivato protetto

Edit: Ecco un semplice esempio di codice:

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; 
} 

Il codice di cui sopra dà error: ‘void D::foo()’ is protected con g ++ 4.5.1 ma compila se protected è sostituito dal public.

+0

Non è questo ciò che funzioni virtuali sono per? –

+2

@BoPersson, le funzioni virtuali sono per il polimorfismo di run-time, CRTP è per il polimorfismo in fase di compilazione. C'è spazio nel mondo per entrambi. Vedi http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern –

+0

@Mark - Ci sono sicuramente, ma se il requisito è di chiamare una funzione protetta in una classe derivata, i virtual sembrano una buona idea. :-) –

risposta

21

Non è un problema a tutti e è risolto con una linea in classe derivata:

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); 
} 
Problemi correlati