std::shared_ptr 向上转换为基类 - 最佳方法

std::shared_ptr upcasting to base class - best method?

本文关键字:基类 最佳 方法 转换 shared ptr std      更新时间:2023-10-16

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

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 相比,在类型安全性方面没有任何好处。

第二个更有意义,因为它是使用真实指针所做的事情的精确转置,同时避免使用显式强制转换,即

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派生