2017-11-11 17 views
0

私はそれを私が望むように動作させるためにこのコードを作るためのヒントを教えてください。 derived_tDerivedになりますが、それは常にBaseです。decltypeを使用した動的多型式の控除

#include <iostream> 
#include <string> 
#include <memory> 

struct Base { 
    virtual std::string me() { return "Base"; } 
}; 

struct Derived : Base { 
    virtual std::string me() override { return "Derived"; } 
}; 

void foo(std::shared_ptr<Base> ptr) { 

    using derived_raw_t = decltype(*ptr); 
    using derived_t = std::remove_reference<derived_raw_t>::type; 

    derived_t* x = new derived_t(); 
    std::cout << x->me() << std::endl; 
} 

int main() { 

    std::shared_ptr<Base> ptr = std::make_shared<Base>(Derived()); 

    foo(ptr); 
} 
+1

を 'decltype'は、この場合、' Base'ある静的(コンパイル時)型を推論します。ファクトリ仮想関数を 'Base'クラスに追加して、このクラスのインスタンスを生成し、それを呼び出して' Derived'のファクトリメソッドを呼び出す 'x'を生成し、' Derived'型の新しいインスタンスを作成することができます。 – VTT

+0

'foo'で派生型が必要なのはなぜですか?あなたは何を達成しようとしていますか? –

+0

これはコンパイル時の機能であるため、 'decltype'を介して行うことはできません。あなたの最善の策は、さまざまな派生クラスでオーバーライドされたベースに 'virtual'関数' create() 'を用意して、それぞれの型のオブジェクトを作成することです。通常、コピーが必要で、対応する関数の名前は 'clone()'です。 –

答えて

2

あなたの目標はあなたの質問から不明です。それにもかかわらず、decltype(e)はコンパイル時に知られている「宣言された型のe」を返すので、ここで期待どおりに動作します。

decltypeを使用して、実行時に派生クラスの実際の型を取得することはできません。多相オブジェクトの実行時のタイプに応じて「複製」する場合は、virtualoverrideを使用できます。例えば:

struct Base { 
    // ... 
    virtual std::shared_ptr<Base> clone() { 
     return std::make_shared<Base>(*this); 
    } 
}; 

struct Derived : Base { 
    // ... 
    virtual std::shared_ptr<Base> clone() { 
     return std::make_shared<Derived>(*this); 
    } 
}; 

あなたは共分散をエミュレートしたい場合は、以下を参照してください。How To Make a clone method using shared_ptr and inheriting from enable_shared_from_this

+0

目的は、派生クラス内でクローン関数を作成して、派生するポインタを返します。私がインスタンスまたはベースを派生したときを知るために別の方法を使用することはできますか?例えば。 typeid()。nameは何とか動作しますが、型のconst char *は必要ありませんが、型自体 – banana36

+0

@ banana36:最後に投稿したリンクを参照してください。 –

+0

ええ、リンクが助けになりました。ありがとう。 – banana36

関連する問題