返回boost :: shared_ptr和从返回的原始指针构造boost :: shared_ptr有什么区别?

时间:2013-08-21 08:26:36

标签: c++ boost shared-ptr

有人告诉我这两种方法的区别,如下所示?

如果我使用CreateBoostContainer,我的代码运行良好。但是,如果我使用CreateContainer,当我尝试在ContainerC上使用shared_from_this时,我会在函数Foo的代码中获得boost :: bad_weak_ptr异常。我只使用一个帖子。

谢谢!

用法:

SceneElementNodeC* poNode(new SceneElementNodeC(CreateBoostContainer()));
SceneElementNodeC* poNode(new SceneElementNodeC(boost::shared_ptr<SceneElementI>(CreateContainer())));

说明:

boost::shared_ptr<SceneElementI> LoaderC::CreateBoostContainer() const
{
    return boost::shared_ptr<SceneElementI>(new ContainerC());
}

SceneElementI* LoaderC::CreateContainer() const
{
    return new ContainerC();
}

SceneElementNodeC:

class SceneElementNodeC
{
    SceneElementNodeC(boost::shared_ptr<SceneElementI> spSceneElement)
    : m_spSceneElement(spSceneElement)
    {};
}

ContainerC:

class ContainerC : public SceneElementI, public boost::enable_shared_from_this<ContainerC>
{
    ContainerC()
    {};

    void Foo(VisitorI* poVisitor)
    {
        poVisitor->Visit(shared_from_this());
    };
}

3 个答案:

答案 0 :(得分:1)

Documentation for enable_shared_from_this

  

要求:enable_shared_from_t这必须是可访问的基类   T. *这必须是T类型的实例t的子对象。那里   必须至少存在一个拥有t的shared_ptr实例p。

注意,“必须至少存在一个拥有t 的shared_ptr实例p。”

如果您使用CreateContainer,那么就没有shared_ptr个实例拥有它。

答案 1 :(得分:1)

Using the raw pointer at all is poor form.这就是为什么通常使用像std::make_shared这样的东西来防止任何可能的内存泄漏。考虑在您创建类的时间点与它与智能指针相关联的时间点之间可能会抛出异常。

话虽如此,我相信这只是boost enable_shared_from_this如何运作的实现细节。

答案 2 :(得分:1)

首先,CreateBoostContainer是一个可怕的名称,Boost库包含数百个组件,包括几个容器,shared_ptr只是Boost的一小部分。如果您之后更改了代码以返回std::shared_ptr,则必须重命名这些函数,那么您是否会将其更改为CreateStdContainer

其次,您未能提供允许重现问题的完整代码,因此根据Stackoverflow的规则,您的问题应该被关闭!我猜你的类型定义如下:

class ContainerC
: public SceneElementI, public boost::enable_shared_from_this<ContainerC>
{
  // ...
};

不同之处在于此功能:

boost::shared_ptr<SceneElementI> LoaderC::CreateBoostContainer() const
{
    return boost::shared_ptr<SceneElementI>(new ContainerC());
}

您使用shared_ptr初始化ContainerC*,以便shared_ptr构造函数能够检测到有enable_shared_from_this基类(通过隐式向上转移到{{1} }})

而在此功能中:

enable_shared_from_this<ContainerC>

通过在创建SceneElementI* LoaderC::CreateContainer() const { return new ContainerC(); } 之前将指针转换为基类来丢失有关对象动态类型的信息。返回的指针是shared_ptr(我假设)没有SceneElementI*基类,所以当该指针稍后用于初始化enable_shared_from_this时,不可能告诉它指向它到类型的基类,也是从shared_ptr派生的。

你可以通过这样做使第一个功能失败:

enable_shared_from_this<ContainerC>

这是等效的,因为它在创建boost::shared_ptr<SceneElementI> LoaderC::CreateBoostContainer() const { SceneElementI* ptr = new ContainerC(); return boost::shared_ptr<SceneElementI>(ptr); } 之前将指针转换为SceneElement*

shared_ptr很聪明并且使用你构造它的指针类型,即使它不是shared_ptr中存储的类型,所以如果你首先向上转换指针,那么{{1} }不能聪明。