9

我正在尝试使用 的循环引用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?因为,我期望间接引用p1后评论1)2). 所以这段代码不需要boost::weak_ptr!那么weak_ptr需要 s 的循环引用是什么?

提前致谢。

4

2 回答 2

23

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

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

于 2012-09-09T12:01:24.867 回答
2

只是想指出:输出的第二行之所以是a5而不是a 4,不是因为s->i++增加了,而是因为shared_ptr<A> s参数是传值的。

调用时

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

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

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

于 2017-10-26T19:12:10.813 回答