In my current project I am using boost::shared_ptr
quite extensively.
Recently my fellow team mates have also started using weak_ptr
. I don't know which one to use and when.
Apart from this, what should I do if I want to convert weak_ptr
to shared_ptr
. Does putting a lock on weak_ptr
to create a shared_ptr
affect my code in other thread?
Shared pointers implement reference counting, weak pointers do not affect reference counting and if you don't have shared pointers to an object, only weak pointers, the object gets deleted and the weak pointers now tell you that the object has been lost.
There are two reasons to use a weak pointer:
So in general, my recommendation would be to use weak pointers only when you know that you want to let the referenced objects be deleted and want to detect that. In other cases use shared pointers (reference counting), or direct pointers, esp. in method local variables when you know that the objects are not going to get deleted. Also errorprone, though, but faster than shared pointers.
N.B. cyclical objects do not need weak pointers, you can use non-cooked, regular pointers instead in most properly constructed programs. Weak pointers less risky, though.
You should probably not be trying to use weak pointers at all unless you are trying to implement a garbage collector, which is not a hot idea in C++ because it's too hard to keep track of everything that could go wrong closely enough.
In general and summary,
Strong pointers guarantee their own validity. Use them, for example, when:
Weak pointers guarantee knowing their own validity. Use them, for example, when:
Lock() on a weak pointer returns a strong pointer; this is how you access the weak pointer. If the object is no longer valid (it's been deleted, etc), then the strong pointer will be NULL, otherwise, it will point at the object. You will need to check this.
It's set up this way so that you cannot accidentally delete the object while you're using it, because you've made a temporary (local) strong pointer, and thus garunteed the object's existence while that strong pointer remains. When you're done using the object, you generally let the strong pointer fall out of scope (or reassigning it), which then allows the object to be deleted. For multithreading, treat them with same care you treat other things that don't have built-in thread safety, noting that the guarantee I mentioned above will hold when multithreading. AFAIK they don't do anything special past that.
The boost shared pointers also have garbage-collector like features, since when the last strong pointer to an object goes away or points somewhere else, the object gets deleted.
There's also the performance and circular dependencies mentioned in the other answers.
Fundamentally, I would say that the boost shared pointer library allows you to not mess up putting together a program, but it is no substitute for taking the time to properly design your pointers, object ownerships and lifetimes. If you have such a design, you can use the library to enforce it. If you don't have such a design, you're likely to run into different problems than before.
Use
weak_ptr
when the objects you create contain cyclical references, i.e.shared_ptr
to an object with ashared_ptr
back to yourself. This is becauseshared_ptr
cannot handle cyclical references - when both objects go out of scope, the mutual referencing means that they are not "garbage collected", so the memory is lost and you have a memory leak. Sinceweak_ptr
does not increase the reference count, the cyclical reference problem does not occur. This also means in general that if you just want to take a pointer to something that is reference counted and do not want to increase its reference count, then useweak_ptr
.Otherwise, you can use
shared_ptr
.For more information, check the Boost documentation.