2011-12-15 8 views
18

CRTP pattern'da, uygulama işlevini türetilmiş sınıfta korumalı olarak tutmak istiyorsak sorunlarla karşılaşıyoruz. Temel sınıfı türetilen sınıfın bir arkadaşı olarak bildirmeli veya something like this kullanmalıyız (Bağlantılı makalede yöntemi denemedim). Uygulama işlevinin türetilmiş sınıfta korunmasını sağlayan başka bir (basit) yol var mı?CRTP with Protected Türetilmiş Üye

Düzenleme:

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

Yukarıdaki kod 4.5.1 ++ g error: ‘void D::foo()’ is protected verir ama protectedpublic ile değiştirilirse derler: Burada, basit bir kod örneğidir.

+0

mi değil bu sanal fonksiyonlar için var? –

+2

@BoPersson, sanal işlevler çalışma zamanı polimorfizmi içindir, CRTP derleme zamanı polimorfizmi içindir. Her ikisinde de dünyaya yer var. Bkz. Http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern –

+0

@Mark - Elbette, ancak türetilmiş bir sınıfta korunan bir işlevi çağırmak gerekirse, sanallar iyi bir uyum gibi görünür. :-) –

cevap

21

bir sorun hiç değil ve türetilmiş sınıfta bir satır ile çözülmüştür:

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