shared_ptr和循环引用

shared_ptr and cyclic references

本文关键字:循环 引用 ptr shared      更新时间:2023-10-16

我尝试使用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的循环引用?因为,在评论1)2)之后,我期望间接引用p1的输出思路不同。因此,此代码不需要boost::weak_ptr!那么,需要weak_ptr s的循环引用是什么呢?

提前谢谢。

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

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之后也是如此。

我只想指出:输出的第二行是5而不是4的原因不是因为s->i++的增加,而是因为shared_ptr<A> s参数是按值传递的。

调用时

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

p4将被复制到另一个shared_pointer,在函数的作用域内暂时将use_count增加一。

也许我在这里扮演的是显而易见的队长(;