web-dev-qa-db-ja.com

std :: shared_ptrでポリモーフィズムを実装するにはどうすればよいですか?

このトピックに関する他の質問をいくつか見ましたが、まだ答えが見つかりません-何かが足りないと思います:

2つの簡単なテストクラスを定義しました。

class TestBase
{

  public:

    TestBase ( ) { };
    ~ TestBase ( ) { };

  protected:

    inline virtual int getInt ( )
    {
        return 0;
    }

};

class TestDerived : public TestBase
{

  protected:

    inline int getInt ( ) override
    {
        return 1;
    }

};

std::shared_ptr:で使用を簡素化するためにtypedefを宣言しました

typedef std::shared_ptr<TestBase> spBase;
typedef std::shared_ptr<TestDerived> spDerived;

問題:これらすべての場合のbaseは実際にはspDerivedのインスタンスですが、これらのshared_ptr宣言を多態的に使用するコードをコンパイルできません。

spBase base;
spDerived derived = static_cast < spDerived > ( base );

エラー: ‘std :: shared_ptr :: shared_ptr(spBase&)の呼び出しに一致する関数がありません

spDerived derived = dynamic_cast < spDerived > ( base );

エラー:「base」(タイプ「spBase {aka class std :: shared_ptr}」)を「spDerived {aka class std :: shared_ptr}」(ターゲットポインタまたは参照ではありません)

spDerived derived = static_pointer_cast < spDerived > ( base );

エラー: 'std :: shared_ptr>'から非スカラー型 'spDerived {aka std :: shared_ptr}'への変換が要求されました

spDerived derived = dynamic_pointer_cast < spDerived > ( base );

エラー: 'std :: shared_ptr>'から非スカラー型 'spDerived {aka std :: shared_ptr}'への変換が要求されました

デフォルトのGCCツールチェーンを備えたUbuntu14.04ボックスでC++ 11を使用しています。コンパイラはgcc-4.9です。私は何が間違っているのですか? shared_pointerを多態的に使用することはできませんか?

17
Vector

渡されたタイプ std::static_pointer_cast および std::dynamic_pointer_cast 最初の型テンプレート引数は変換されたポインタの型自体の型であり、smartポインタ型ではありません:

static_pointer_cast<T>(arg);
                .~~~^  
                v 
template <class T, class U> 
           .~~~~^  
           v 
shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r);


dynamic_pointer_cast<T>(arg);
                .~~~~^  
                v 
template <class T, class U> 
           .~~~~^  
           v 
shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r);

そうは言っても、あなたはそれを以下のように呼ぶことができます:

spBase base = std::make_shared<TestDerived>();
spDerived derived = std::dynamic_pointer_cast<spDerived::element_type>(base);
// or:
spDerived derived2 = std::dynamic_pointer_cast<TestDerived>(base);
17
Piotr Skotnicki