0

有人可以告诉我这两种方法在如下使用时的区别吗?

如果我使用 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();
}

场景元素节点C:

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

集装箱C:

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

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

3 回答 3

1

enable_shared_from_this 的文档

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

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

如果您使用CreateContainer,则没有shared_ptr拥有它的实例。

于 2013-08-21T08:34:40.750 回答
1

完全使用原始指针是不好的形式。这就是为什么通常使用类似std::make_shared- 来防止任何可能的内存泄漏的原因。考虑到在新建类的点和它与智能指针关联的点之间可能会引发异常。

话虽如此,我相信这只是 boost 的enable_shared_from_this工作原理的一个实现细节。

于 2013-08-21T08:35:28.050 回答
1

首先,CreateBoostContainer这是一个可怕的名字,Boost 库包含数百个组件,包括几个容器,shared_ptr只是 Boost 的一小部分。如果您后来更改代码以返回 astd::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您使用 a初始化,ContainerC*因此shared_ptr构造函数能够检测到有一个enable_shared_from_this基类(通过隐式向上转换为enable_shared_from_this<ContainerC>

而在这个函数中:

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

在创建shared_ptr. 返回的指针SceneElementI*(我假设)没有enable_shared_from_this基类,因此当该指针稍后用于初始化 ashared_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_ptrshared_ptr很聪明,并利用了您构造它的指针类型,即使那不是存储在shared_ptr.

于 2013-08-21T09:11:18.127 回答