2011-12-15 12 views
18

CRTP patternでは、派生クラスの実装機能を保護された状態に保つために問題が発生します。派生クラスのフレンドとして基本クラスを宣言するか、something like thisを使用する必要があります(私はリンクされた記事でこのメソッドを試していません)。派生クラスの実装関数を保護された状態に保つことを可能にする他の(簡単な)方法がありますか?保護された派生メンバーを持つCRTP

編集:ここでは、簡単なコードの例である:

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

上記のコードはG ++ 4.5.1でerror: ‘void D::foo()’ is protectedを与えるがprotectedpublicによって置換される場合にコンパイル。

+0

これは、仮想関数がのためにあるものではないですか? –

+2

@BoPersson、仮想関数は実行時多型、CRTPはコンパイル時多型です。両方のための世界の余地があります。 http://market.wikipedia.org/wiki/Curiously_recurring_template_patternを参照してください。 –

+0

@マーク - 確かにありますが、派生クラスの保護された関数を呼び出す必要がある場合、バーチャルは適切に見えます。 :-) –

答えて

21

それはまったく問題ではないと派生クラスで1行で解決されています

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); 
} 
関連する問題