2016-03-30 4 views
0

CRTPを使用しているときにオブジェクトスライスの問題が発生しました。次の模擬は私の問題を示しています。上記のコードをコンパイルするCRTPを使用しているときのオブジェクトのスライシング

#include <memory> 

class CrtpGenr 
{ 
}; 

template<class t_object> 
class CrtpBase : public CrtpGenr 
{ 
    public: 
     static 
     auto create() -> std::unique_ptr<t_object> { 
      return(std::unique_ptr<t_object>(new t_object)); 
     } 
     void funct1(){} 
}; 

class CrtpDirv1 : public CrtpBase<CrtpDirv1> 
{ 
    public: 
     void funct2(){} 
}; 

class CrtpDirv2 : public CrtpBase<CrtpDirv2> 
{ 
    public: 
     void funct2(){} 
}; 


int main() 
{ 
/* 
    // This works 
    std::unique_ptr<CrtpDirv1> crtp_obj = CrtpDirv1::create(); 
    crtp_obj->funct1(); 
    crtp_obj->funct2(); 
*/ 

    std::unique_ptr<CrtpGenr> crtp_obj1 = static_cast<std::unique_ptr<CrtpGenr>>(CrtpDirv1::create()); 
    std::unique_ptr<CrtpGenr> crtp_obj2 = static_cast<std::unique_ptr<CrtpGenr>>(CrtpDirv2::create()); 
    crtp_obj1->funct1(); 
    crtp_obj1->funct2(); 

    return 0; 
} 

は私に次のエラー与える:

main.cpp: In function 'int main()': 
main.cpp:47:16: error: 'class CrtpGenr' has no member named 'funct1' 
crtp_obj1->funct1(); 
      ^
main.cpp:48:16: error: 'class CrtpGenr' has no member named 'funct2' 
crtp_obj1->funct2(); 

を私はCrtpGenrにCrtpDirv1とCrtpDirv2クラスをキャストできるようにしたいと思います。これは、CrtpDirv1またはCrtpDirv2のオブジェクトを保持するためのCrtpGenr型のコンテナを定義できるようにするためです。私は間違って何をしていますか?

+0

'static_cast'はコンパイルすべきではありません。すべてのエラーを提供していますか? –

+0

@ Alf:はい私はcoliruで同じ正確なコードをコンパイルしました。私が提供したエラーはそこに与えられているものです。 [リンク](http://coliru.stacked-crooked.com/a/5a643b61336c250c) – vixiv

+0

@alf - static_castsはうまくコンパイルされます(http://cpp.sh/8zg6)。しかし、誰がなぜ47行目と48行目がコンパイルされると思うのか分かりません。 – Arunas

答えて

0

*crtp_obj1はタイプCrtpGenrのです - あなたはライン48にクレーム、全体シェバングがCrtpGenrから派生したので、これは、実際には真です。したがって、static_castsはコンパイルされます。

しかし、あなたは相続財産を後方に持っています。 CrtpGenrの定義を見てください:

class CrtpGenr 
{ 
}; 

それは方法がありません。コンパイラがそのオブジェクトの1つを呼び出そうとするのを、なぜ期待していますか?

一般的な基底型のオブジェクトをコンテナ(たとえば `std :: list ')に入れることができるようにキャストすると、これを行うことができます。しかし、そのオブジェクトの特定のメソッドを呼び出す場合は、コンパイラに、あなたが作成した型にそのポインタをキャストすることによって実際にどのようなオブジェクトであるかを伝える必要があります。

継承と多型をもう少し詳しく調べることができます。たとえば、おそらくCrtpGenrクラスは、派生クラスが実装する仮想メソッドfunct1()を持つことができます。

+0

はい、このキャストは、コンテナ内で派生クラスを保持できるように行われます。しかし、何らかの理由で私はcrtp_objsを適切なDerivedクラスにキャストできません。どうやったら元気に戻すことができるかも教えてください。 – vixiv

+0

"あなたが作成したタイプにそのポインタをキャストする"ことを指摘していただきありがとうございます。私は今、私が望むようにコードを手に入れました。 – vixiv

関連する問題