I was trying with the cyclic references for boost::shared_ptr
, and devised following sample:
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;
}
which outputs
4
5
4
~A : 4
Is it that I've misinterpreted the cyclic references mentioned for boost::shared_ptr
? Because, I expected different output thinking of indirect references to p1
after comments 1)
and 2)
.
So this code doesn't require boost::weak_ptr
! So what are the cyclic references where weak_ptr
s would be required?
Thanks in advance.
Yes, you have misinterpreted this. In your example, all the pointers are pointing to the same object, not forming any cycles.
The assignment of p4 to p2 is a no-op, since those pointers were already equal to begin with.
Here's an example with real cyclic references, maybe that will clear things up:
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
}
You can even make this even simpler:
void main()
{
std::shared_ptr<A> x=std::make_shared<A>();
x->ptr = x; // never die! x keeps itself alive
}
In both examples, the objects in the shared_ptrs are never destructed, even after you leave main.
Just wanted to point out: the reason why the second line of the output is a 5
and not a 4
is not because of the s->i++
increase, but because the shared_ptr<A> s
parameter is being passed by value.
Upon calling
p1 = changeI(p4); // 2) 2nd cyclic ref.
p4
will be copied to yet another shared_pointer
, temporarily increasing the use_count
by one during the scope of the function.
Maybe I'm playing captain obvious here (;