我尝试使用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
的循环引用?
提前致谢。
答案 0 :(得分:22)
是的,你误解了这一点。在您的示例中,所有指针都指向同一个对象,而不是形成任何循环。
将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
}
在这两个示例中,即使在离开main之后,shared_ptrs中的对象也永远不会被破坏。
答案 1 :(得分:0)
只是想指出:输出的第二行是5
而不是4
的原因不是因为s->i++
增加,而是因为{{ 1}}参数按值传递。
致电
shared_ptr<A> s
p1 = changeI(p4); // 2) 2nd cyclic ref.
将被复制到另一个p4
,在函数范围内暂时将shared_pointer
增加一个。
也许我在这里扮演明显的队长(;