std :: shared_ptr upcasting到基类 - 最好的方法?

时间:2014-01-09 11:21:34

标签: c++ shared-ptr

哪种转换更好,有什么区别?

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;
}

3 个答案:

答案 0 :(得分:16)

shared_ptr的其他用例一样,您应该更喜欢使用make_shared而不是手动构建shared_ptr

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

这基本上是您的第2版,加上the various benefits of make_shared

版本1会做一些不必要的事情:首先构建一个临时的shared_ptr<Derived>,然后将dynamic_cast的内容添加到基类指针(这里static_cast就足够了)然后将该指针存储在不同的shared_ptr<Base>中。因此,您有许多不必要的运行时操作,但没有类型安全性优于第2版。

答案 1 :(得分:3)

第二个更有意义,因为它是对真实指针所做的完全转换,同时避免使用显式转换,即

Base* ptr = new Derived();

另一种选择是使用std::make_shared指定Derived作为模板参数,即:

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

答案 2 :(得分:0)

似乎没有提到最明显的答案所以我会补充说完整性。

您不需要演员表,最好的方法是:

#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

派生