どの変換が優れていますか、そして違いは何ですか?
class Base
{};
class Derived : public Base, public std::enable_shared_from_this<Derived>
{};
int main(int argc, const char * argv[])
{
std::shared_ptr<Base> ptr1 = std::dynamic_pointer_cast<Base>(std::shared_ptr<Derived>(new Derived())); // version 1
std::shared_ptr<Base> ptr2 = std::shared_ptr<Derived>(new Derived()); // version 2
return 0;
}
shared_ptr
の他のユースケースと同様に、make_shared
を手動で作成するのではなく、shared_ptr
を使用することをお勧めします。
std::shared_ptr<Base> ptr2 = std::make_shared<Derived>();
これは基本的にバージョン2に加えて、 make_shared
のさまざまな利点 です。
バージョン1は、多くの不要な処理を実行します。最初に一時的なshared_ptr<Derived>
を作成し、次にその内容を基本クラスポインタにdynamic_cast
します(ここではstatic_cast
で十分です)。そのポインタを別のshared_ptr<Base>
に格納します。したがって、不要なランタイム操作がたくさんありますが、バージョン2よりも型の安全性に関する利点はありません。
2つ目は、明示的なキャストの使用を避けながら、実際のポインターで行われることの正確な転置であるため、より意味があります。
Base* ptr = new Derived();
別のオプションは、 std::make_shared
テンプレートパラメータとしてDerived
を指定します。つまり:
std::shared_ptr<Base> ptr2 = std::make_shared<Derived>();
最も明白な答えは言及されていないようですので、完全を期すためにそれを追加します。
キャストは必要ありません。それを実現するための最良の方法は次のとおりです。
#include <memory>
class Base
{};
class Derived : public Base, public std::enable_shared_from_this<Derived>
{};
int main(int argc, const char * argv[])
{
std::shared_ptr<Derived> ptr1 = std::make_shared<Derived>();
std::shared_ptr<Base> ptr2 = ptr1; // no CAST NEEDED HERE AS YOU SEE :)
return 0;
}
この場合、enable_shared_from_this
から派生しても何も変更されません。次のクラスを使用することもできます(コードを少し読みやすくします)
class Base
{};
class Derived: public Base
{};
もちろん、実装の詳細はわかりません。そのため、enable_shared_from_this
から派生する必要がある可能性が非常に高くなります。