7

我目前正在整理一个严重依赖的应用程序,shared_ptr到目前为止一切看起来都很好——我已经完成了我的功课shared_ptr,并且对使用s的一些陷阱有一个很好的了解。

最公认的问题之一shared_ptr是循环依赖——这些问题可以通过存储weak_ptr不影响链上对象生命周期的 s 来解决。但是,我正在努力解决需要通过 a 存储指向外部对象的指针的时间weak_ptr-我不确定它是否被禁止、不鼓励或是否安全

下图描述了我的意思(黑色箭头表示shared_ptr;虚线表示weak_ptr):

替代文字 http://img694.imageshack.us/img694/6628/sharedweakptr.png

  • 父级包含shared_ptrs 到两个子级,这两个子级都使用 a 指向父级weak_ptr
  • 在第一个孩子的构造函数中,我通过父级检索weak_ptr指向第二个孩子的指针并将其存储在本地。

代码如下所示:

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>

class child;
class child2;
class parent;

class parent : public boost::enable_shared_from_this<parent>
{
public:
    void createChildren()
    {
        _child2 = boost::make_shared<child2>(shared_from_this());
        _child = boost::make_shared<child>(shared_from_this());
    }

    boost::shared_ptr<child> _child;
    boost::shared_ptr<child2> _child2;
};

class child
{
public:
    child(boost::weak_ptr<parent> p)
    {
        _parent = p;
        _child2 = boost::shared_ptr<parent>(p)->_child2; // is this safe?
    }

    boost::weak_ptr<parent> _parent;
    boost::shared_ptr<child2> _child2;
};

class child2
{
public:
    child2(boost::weak_ptr<parent> p)
    {
        this->_parent = p;
    }

    boost::weak_ptr<parent> _parent;
};

int main()
{
    boost::shared_ptr<parent> master(boost::make_shared<parent>());
    master->createChildren();
}

我已经对此进行了测试,它似乎工作正常(我没有收到任何内存泄漏的报告),但是我的问题是:这安全吗?如果没有,为什么不呢?

4

3 回答 3

6

子构造函数看起来像您调用它的方式是安全的。但是一般来说它并不安全。

问题是由于在子构造函数中传入了一个 weak_ptr 作为参数。这意味着您需要担心弱指针是否指向不再存在的对象。通过将此参数更改为 shared_ptrs 并在存储时转换为 weak_ptr,我们知道该对象仍然存在。这是变化:

child(boost::shared_ptr<parent> p)
{
    _parent = p;
    _child2 = p->_child2; // This is this safe
}
于 2010-01-26T12:59:30.710 回答
3

shared_ptr 最常见的问题之一是循环依赖——这些问题可以通过存储不影响链上对象生命周期的 weak_ptr 来解决。

错误的。这种循环依赖存在或不存在。

如果问题存在,那么弱引用根本不是一种选择。

需要通过weak_ptr存储指向外部对象的指针

weak_ptr几乎不需要。

很少有非常具体的情况weak_ptr是合适的,但大多数情况下它是shared_ptr邪教的一部分:他们不是随机抛出shared_ptr问题,而是随机抛出shared_ptr一半weak_ptr(如 SO 所示)。

于 2011-10-08T05:57:43.817 回答
0

如果 'p' 已经(以某种方式)被破坏,你会得到 bad_weak_ptr 异常。因此,孩子 ctor 期望异常是安全的,否则不安全。

于 2010-01-26T12:38:32.517 回答