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.
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 :)
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.
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.
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
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.
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....
"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
来源:https://stackoverflow.com/questions/1119962/smart-pointers-when-where-and-how