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.
The only difference between weak_ptr and shared_ptr is that the weak_ptr allows the reference counter object to be kept after the actual object was freed. As a result, if you keep a lot of shared_ptr in a std::set the actual objects will occupy a lot of memory if they are big enough.
In short: Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.
The difference is that std::make_shared performs one heap-allocation, whereas calling the std::shared_ptr constructor performs two.
The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.
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 (;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With