暗黙的な変換演算子の使用はお勧めしません。C++11 ではexplicit
、単一引数のコンストラクターだけでなく、変換演算子にもキーワードを追加できます。self()
C++03 コードの場合、またはなどの明示的に名前が付けられた変換関数を使用できますdown_cast()
。
さらに、Base
CRTP、つまり静的ポリモーフィズムを有効にするためにクラスを使用しているようです。つまり、呼び出している特定のクラスをコンパイル時に知る必要があります。したがって、 CRTP インターフェイスを実装する場合を除いて、パブリック コードで参照Derived
を使用する必要はありません。const Base&
私のプロジェクトには、クラス テンプレートがありenable_crtp
ます。
#include <type_traits>
#include <boost/static_assert.hpp>
template
<
typename Derived
>
class enable_crtp
{
public:
const Derived& self() const
{
return down_cast(*this);
}
Derived& self()
{
return down_cast(*this);
}
protected:
// disable deletion of Derived* through Base*
// enable deletion of Base* through Derived*
~enable_crtp()
{
// no-op
}
private:
// typedefs
typedef enable_crtp Base;
// cast a Base& to a Derived& (i.e. "down" the class hierarchy)
const Derived& down_cast(const Base& other) const
{
BOOST_STATIC_ASSERT((std::is_base_of<Base, Derived>::value));
return static_cast<const Derived&>(other);
}
// cast a Base& to a Derived& (i.e. "down" the class hierarchy)
Derived& down_cast(Base& other)
{
// write the non-const version in terms of the const version
// Effective C++ 3rd ed., Item 3 (p. 24-25)
return const_cast<Derived&>(down_cast(static_cast<const Base&>(other)));
}
};
このクラスは、次のような CRTP 基本クラス ISomeClass からプライベートに派生します。
template<typename Impl>
class ISomeClass
:
private enable_crtp<Impl>
{
public:
// interface to be implemented by derived class Impl
void fun1() const
{
self().do_fun1();
}
void fun2()
{
self().do_fun2()
}
protected:
~ISomeClass()
{}
};
さまざまな派生クラスは、次のような独自の方法でこのインターフェイスを実装できます。
class SomeImpl
:
public ISomeClass<SomeImpl>
{
public:
// structors etc.
private:
// implementation of interface ISomeClass
friend class ISomeClass<SomeImpl>;
void do_fun1() const
{
// whatever
}
void do_fun2()
{
// whatever
}
// data representation
// ...
};
の外部コード呼び出しfun1
はclass SomeImpl
、の適切な const または非 const バージョンに委譲され、self()
down_castingclass enable_crtp
の後に実装do_fun1
が呼び出されます。適切なコンパイラを使用すると、すべての間接化を完全に最適化する必要があります。
注: および の保護されたデストラクタはISomeClass
、ベース ポインタを介してオブジェクトenable_crtp
を削除しようとするユーザーに対してコードを安全にします。SomeImpl*