33

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

上記のコードはerror: ‘void D::foo()’ is protectedg++ 4.5.1 で提供されますが、protectedが に置き換えられた場合はコンパイルされpublicます。

4

3 に答える 3

35

それはまったく問題ではなく、派生クラスの 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 );
}
于 2011-12-15T18:08:00.220 に答える