It's been a while I coded in C/C++, and now I need its efficiency for a project I'm doing.
What I understand from this shared_ptr is that it basically deletes the object when I need it to. So, if, for example, my object has a vector of shared_ptr, I wouldn't have to worry about iterating through the vector and deleting each element in the destructor? In other words, I don't have to worry about memory management as long as I use these? Or am I totally misunderstanding this? It sounds too good to be true.
You have to understand that shared pointers are implemented using a reference count, that means that if you have cycles in your pointer graph then the objects will not be released. That is, if a points to b and b points to a but nothing points to a or b, then neither a nor b will be released because they both have a reference count of '1'.
Boost provides weak pointers to get around this, which allows you to store a pointer to a shared object without incrementing its reference count. Weak pointers provide a layer of safety in that attempting to dereference the pointer after the shared pointer has been released will raise an exception rather than crashing the program.
Shared pointers are also quite expensive (at least compared to a raw pointer) in performance terms - but it's better to use them and then remove them once a profiler identifies a bottleneck rather than not use them everywhere.
Other than that, yes, they are very useful for managing dynamically allocated objects.
Edit: Another gotcha (that's mentioned on the boost pages) is to avoid "temporary" shared_pointers:
func(A(), boost::shared_ptr<B>(new B));
because the compiler is allowed to optimise this as
tmp1 = new B;
tmp2 = A();
tmp3 = boost::shared_ptr<B>(tmp1)
func(tmp2,tmp3)
which might look OK on first glance, but if A() happens to throw an exception then B has been allocated, but the shared_ptr hasn't gotten a hold of it yet, so the pointer never gets released.
You can do this but it's generally a bad idea. For a start you may lose some or all of the efficiency that you think you might be gaining.
More importantly, it sounds like you are trying to avoid designing your code. Java has gc, so you don't have to worry about memory management but you should still be concerned about object lifetimes. If you are not clear about who owns what you are likely to end up with a muddled design.
C++ gives you a lot of options when it comes to object lifetimes, not every complex object needs to be allocated on the heap. shared_ptr
should be used for objects that require shared ownership (as it's name implies) but this should be a positive design decision. There are better ways to own an object if shared or transferable ownership aren't required.
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