views:

345

answers:

7

First off, since there are different kinds of smart pointers, I'd like to focus this question on two of them: reference counted intrusive and non-intrusive smart pointers. The question is asked individualy for each pointer type.

I am not really sure how to formulate my question, so here's what I'm not asking: I am not asking why, or when, are smart pointers needed. Neither which type of smart pointer should I use and for what.

Here is what I'm asking, and I hope it's clear enough: When dealing with "smartly-managed" objects, in which contextes should I use which pointer semantics? That is, smart pointer semantics, raw pointer semantics, something else (Such as a reference to a smart pointer)?

It's preety obvious that when I "store" a pointer to an object (object being a reference counted memory entity), such as a global pointer, or as a class member, it should be a smart pointer, so it would claim ownership, but what about other situations?

When I'm passing a pointer as a function argument, should it be a smart-pointer, a raw pointer, a reference to a smart pointer, or maybe something else? What about returned pointers? Local pointers? so on...

Ofcourse, I could use smart pointers everywhere, which is the safest option, but I am feeling that this is really unnecessary and adds overhead.

+1  A: 

IMHO, sometimes it's better to do things faster than to have a minor performance improvement. I'm supposing you will do things faster if you always use smart pointers.

My suggestion: Use smart pointers everywhere. Then use a profiler to see if it generates considerable overhead. Where it does, change it :)

Samuel Carrijo
A: 

In my experience, when I'm passing the object to a function that doesn't need to store a reference to the object (or otherwise, that calling the function does not affect the lifetime of the object in any way), then it's safe to pass the object by reference. This makes the code less "tied" to the smart pointer type.

On the other hand, always using the smart pointer type is "always safe", so when in doubt....

Chris Jester-Young
+1  A: 

If you are tyring to contrast "smart pointer semantics" and "raw pointer semantics", you are incorrectly assuming that you can group all "smart pointer semantics" together. I disagree. The difference between boost::scoped_ptr and boost::shared_ptr is of the same order of magnitude as the difference bwteeen boost::shared_ptr and T*

When you "store" a pointer to an object as a class member, you haven't really said a lot about the semantics. If the referenced object is logically a member ("owned"), then yes, you'd want a smart pointer. But one with very specific semantics: single ownership. This means no shared ownership, nor a weak pointer, to name two other common smart pointers. On the other hand, if you're storing a pointer to a error logging object, you probably want a weak pointer. This will prevent you from crashing during shutdown - the weak pointer will be NULL if the log is gone.

Similarly, when you're returning a pointer from a function, the actual semantics of the case will dictate the type of pointer you need. Not the simple fact that it's returned from a function.

MSalters
+3  A: 

I suggest you limit the use of pointers, smart or otherwise, as much as possible. I don't know your background, but many people coming from languages like Java or C# use pointers when they should be really using values and call by reference. Use of pointers in a C++ program should be relatively rare.

anon
Smart pointers are useful when you have objects that have to live for a long time, and need to have shared and/or transferable ownership. References are fine and good if ownership is constrained to a single place.
Chris Jester-Young
Very few objects need to live for a long time and need to be shared or have ownership transferred. Most code deals with short-lived values.
anon
That may well be the case in the sort of code you work with. It isn't for mine, neither here nor in my last non-contract job. (It was the case in my last contract job.) If somebody is going to need pointers, or if any other way of handling the situation is bad, then they should use smart pointers.
David Thornley
+1 for Neil. There are cases where shared ownership is truly needed, but (at least in my experience) in most cases you do know the life scope of your objects and if you do there is no need for shared ownership.
Nemanja Trifunovic
@Nemanja Thanks for the support - I think I should have made it clear I meant shared ownership, rather than simple sharing, but editing comments on SO is so much trouble!
anon
+1  A: 

In many situations, the use of smart pointers relate to memory management and/or exception handling. The STL auto_ptr neatly manage destruction even in complex try/catch environment. Smart pointers are useful to delegate the lifecycle of the pointed object to the smart pointer. It is generally needed whenever it is difficult to follow the paradigm "destroy your object where you have created it". A reference type smart pointer can be useful when you cannot easily manage a shared object. I prefer to solve this sort of problem with a good architecture, but there is cases where smart pointers are the best way.

neuro
+1  A: 

My list of pointers:

  • normal usage: normal members and (const) references to them
  • sharing and keeping the object alive (owners, containers): shared_ptr
  • sharing, but not keeping alive (users): weak_ptr
  • scoped usage: scoped_ptr
  • other usages (output-parameter,...): raw pointer
stefaanv
A: 
"When I'm passing a pointer as a function argument, should it be a smart-pointer, a raw
pointer, a reference to a smart pointer, or maybe something else? What about returned
pointers? Local pointe rs? so on..."

my 2p, unless you have an obvious reason to use shared_ptrs don't:

Don't pass pointers to functions, pass references to the objects

Don't return pointers from functions, pass objects as non-const references and change those objects

When creating local objects on the heap use scoped_ptr

Patrick
However, in many applications shared_ptr<> is the exact right thing to do. Your advice is hardly universally good.
David Thornley
I thought that was covered in the "unless you have an obvious reason" bit... my advice is aimed at someone who seems to want to use shared_ptrs for everything
Patrick