Re: auto_ptr vs. boost shared_ptr
Thomas Tutone wrote:
Robster wrote:
I've just read the boost documentation on shared_ptr
(http://www.boost.org/libs/smart_ptr/shared_ptr.htm) and it
was not clear to me what advantage using shared_ptr over
std::auto_ptr would be.
A shared_ptr is more versatile (but potentially slightly
slower) than an auto_ptr.
An auto_ptr is more versatile than a shared_ptr, but cannot be
used in certain circomstances:-).
The two have, intentionally, very different semantics. If you
need the semantics of auto_ptr, especially, release(), you
cannot use shared_ptr. If you need the assignment and copy
semantics of shared_ptr, you cannot use auto_ptr. One is not
more versatile than the other; they are simply different, and
are used for different things.
Do you use the Standard Library's containers (like vector,
list, map, etc.)? They work with shared_ptr, but not with
auto_ptr. In other words, you can create, for example, a
vector< shared_ptr< int > >, but you can't create a vector<
auto_ptr< int > >:
vector< shared_ptr< int > > v1; // OK.
vector< auto_ptr< int > > v2; // Undefined Behavior, but probably a
compile error.
True, but most of the time, I find that raw pointers are best
here. Of course, I usually use the Boehm collector, so I don't
need a surrogate for garbage collection.
Relatedly, you can't have multiple auto_ptrs that point to the same
underlying object.
Exactly. That can be an enormous advantage in certain cases.
You can with shared_ptr. In other words, the following code
doesn't work with auto_ptr:
typedef std::auto_ptr<int> smart_ptr;
smart_ptr p1 = new int(0);
smart_ptr p2 = p1;
*p1 = 1; // Undefined Behavior here.
But if you substitute
typedef shared_ptr<int> smart_ptr;
for the first typedef, it works properly.
On the other hand:
std::auto_ptr< Message > p( new Message( ... ) ) ;
myMessageQueue.send( p ) ;
// Can't access the message by mistake here...
If all you want is automatic garbage collection, why use a
surrogate, when you can use the real thing; the Boehm collector
is generally the best solution. If you're using smart pointers
for more than just garbage collection, however, then you should
choose the pointer which has the necessary semantics:
boost::scoped_ptr:
If someone accidentally tries to copy it, you get a compile
time error. Ideal for variants on the pimpl idiom.
std::auto_ptr:
Transfers ownership. Ideal for return values of functions,
for example (allowing the caller to decide his own ownership
policy), and in cases where it would be a mistake to
continue accessing the object (very important in threaded
environments---once the other thread has ownership, any
access by the originating thread is undefined behavior).
boost::shared_ptr:
Use when any timely action is required when the last
reference (of a set of references originating from a common
root) is necessary. I use it mainly for returning a pointer
to a mutable singleton, which requires locked access---the
"destructor" does not destroy the object, but only frees up
the lock.
With care, it can also serve as a surrogate for garbage
collection, if for some reason you cannot use the Boehm
collector. But this requires extreme care, in order to
avoid cycles.
--
James Kanze kanze.james@neuf.fr
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]