【问题标题】:shared_ptr and cyclic referencesshared_ptr 和循环引用
【发布时间】:2012-09-02 12:36:00
【问题描述】:

我正在尝试使用 boost::shared_ptr 的循环引用,并设计了以下示例:

class A{ // Trivial class
public:
    i32 i;
    A(){}
    A(i32 a):i(a){}
    ~A(){
        cout<<"~A : "<<i<<endl;
    }
};

shared_ptr<A> changeI(shared_ptr<A> s){
    s->i++;
    cout<<s.use_count()<<'\n';

    return s;
}

int main() {

    shared_ptr<A> p1 = make_shared<A>(3);
    shared_ptr<A> p2 = p1;
    shared_ptr<A> p3 = p2;
    shared_ptr<A> p4 = p3;

    p1 = p4; // 1) 1st cyclic ref.
    cout<<p1.use_count()<<'\n';

    p1 = changeI(p4); // 2) 2nd cyclic ref.

    cout<<p1.use_count()<<'\n';

//  putchar('\n');
    cout<<endl;
}

哪个输出

4
5
4

~A : 4

是不是我误解了boost::shared_ptr 提到的循环引用?因为,我期望在 cmets 1)2) 之后对 p1 的间接引用会有不同的输出思考。 所以这段代码不需要boost::weak_ptr!那么需要weak_ptrs 的循环引用是什么?

提前致谢。

【问题讨论】:

  • 5 的中间结果是由于将共享指针对象按值传递给函数导致共享指针的新副本为 s

标签: c++ shared-ptr weak-ptr cyclic-reference


【解决方案1】:

只想指出:输出的第二行之所以是5而不是4不是因为s-&gt;i++增加,而是因为shared_ptr&lt;A&gt; s参数被传递价值。

调用时

p1 = changeI(p4); // 2) 2nd cyclic ref.

p4 将被复制到另一个shared_pointer,在函数范围内临时将use_count 加一。

也许我在这里扮演队长的角色很明显(;

【讨论】:

    【解决方案2】:

    是的,你误解了这一点。在您的示例中,所有指针都指向同一个对象,而不是形成任何循环。

    p4 到 p2 的赋值是无操作的,因为这些指针在开始时就已经相等了。

    这是一个真正的循环引用的例子,也许可以解决问题:

    struct A
    {
      std::shared_ptr<A> ptr;
    };
    
    void main()
    {
      std::shared_ptr<A> x=std::make_shared<A>();
      std::shared_ptr<A> y=std::make_shared<A>();
    
      x->ptr = y; // not quite a cycle yet
      y->ptr = x; // now we got a cycle x keeps y alive and y keeps x alive
    }
    

    你甚至可以让它变得更简单:

    void main()
    {
      std::shared_ptr<A> x=std::make_shared<A>();
    
      x->ptr = x; // never die! x keeps itself alive
    }
    

    在这两个示例中,shared_ptrs 中的对象永远不会被破坏,即使在您离开 main 之后也是如此。

    【讨论】:

    • 感谢您的澄清。现在在您的示例中,x 会在进程结束时死掉(在 Linux 中 - 我使用的是 Ubuntu 10.04),还是取决于操作系统是否会持续到重新启动?
    • 是的,严格来说这是操作系统的工作。我知道的所有操作系统都可以做到这一点。一些嵌入式操作系统可能不会。
    • 好的,所以当某些具有成员指针的对象直接/间接指向自身时,就会形成循环。有没有其他的场景?请告诉我。
    • 不,这就是循环的定义;一个直接或间接指向自身的对象,因此永远不会丢失那个引用。
    • main返回时x和y的use_count()会从2减少到1吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    相关资源
    最近更新 更多