2016-04-15 6 views
4

私はクラスの、このような階層構造を持っている:複数の派生クラスでCRTPを使用し、ポリモーフィックで使用できますか?

template <class Type> 
class CrtpBase 
{ 
protected: 
    Type& real_this() 
    { 
     return static_cast<Type&>(*this); 
    } 
}; 

template <class ChildType> 
class Base : CrtpBase<ChildType> 
{ 
public: 
    void foo() 
    { 
     this->real_this().boo(); 
    } 
}; 

class Derived1 : public Base<Derived1> 
{ 
public: 
    void boo { ... } 
}; 

class Derived2 : public Base<Derived2> 
{ 
public: 
    void boo { ... } 
}; 

事は、私はこのように私のクラスを使用する場合は、次のとおりです。

std::vector<Base*> base_vec; 
base_vec.push_bach(new Derived1()); 
base_vec.push_bach(new Derived2()); 
......... 
base_vec[0]->foo(); 

しかし、すべての基底クラスが派生しているため、これは、可能ではありませんクラスは異なります(実際にはBaseは型ではなく、テンプレートです)。ですから、複数の派生クラスを持つcrtpと多態性を併用する方法はありますか?確かにそこに

答えて

3

です、あなたはあまりにも適切な非テンプレートベースクラスを追加する必要があります。

class AbstractBase 
{ 
public: 
    virtual ~AbstractBase() {} 

    virtual void foo() = 0; 
}; 


template <class ChildType> 
class Base : CrtpBase<ChildType>, public AbstactBase 
{ 
    void foo() override { this->real_this().boo(); } 
}; 

その後、std::vector<AbstractBase*>としてあなたのベクトルを宣言します。

これは、実際にはCRTPを使用して回避しようとしていたダイナミックディスパッチのオーバーヘッドをもたらしますが、動的ディスパッチはC++で実行時ポリモーフィズムを取得する唯一の方法です。

でも、それはまだ有益なことがあります。たとえば、fooの実装がすべての派生クラスで共有されているが、多くの異なるbooスタイル関数(それぞれの派生クラスが異なる実装を持つ)を呼び出す場合は、fooを呼び出すときに一度動的ディスパッチコストを支払うだけですその後、foo内のすべてのコールがCRTPスタイルで静的に発信されます。一方

それはfooboo様機能に一つだけの呼び出しだ場合、あなたにもこれCRTPを取り払う、ベースに非仮想fooを入れ、booが仮想ことがあります。非仮想ディスパッチ(foo)とバーチャルディスパッチ(boo)のコストは同じです。


サイドノートでは、スマートポインタをstd::vectorに保存することを強く検討する必要があります。 所有する生ポインタは悪い習慣です。

+0

私がcrtpを使用したすべてのことは、仮想関数を避けることでした。このソリューションの意味は何ですか? crtpクラスを導入して仮想関数を回避し、抽象クラスを仮想関数で使用して問題を解決しますか?ナンセンス – user1289

+1

@ user1289まあ、CRTPはコンパイル時のソリューションです。つまり、さまざまなタイプに基づいてコンパイル時にディスパッチすることができます。次に、同じタイプのものを要求しました。これは、ランタイムディスパッチとそれに伴う仮想関数を意味します。 'boo()'がまだ静的にディスパッチされていることに注意してください。 – Angew

+0

@Angew、crtpなしでも、必要なランタイム・ディスパッチは1つしかないでしょう。この場合は、ランタイムとスタティックが1つありますが、crtpを使用しない場合よりも悪いことがあります。おそらく私の質問には解決策がない、ちょうどこれにハックがあるかどうかをチェックしたいと思った。 – user1289

関連する問題