shared_ptr vs std::auto_ptr

S

SerGioGio

Hello !

When a ref. counted smart pointer (template) class is available (like
boost::shared_ptr), is there any (semantic) reason to still use
std::auto_ptr rather than this smart pointer ? Or should one use shared_ptr
for every cases ?

Thanks in advance for your remarks !

SerGioGio
 
H

Howard Hinnant

| Hello !
|
| When a ref. counted smart pointer (template) class is available (like
| boost::shared_ptr), is there any (semantic) reason to still use
| std::auto_ptr rather than this smart pointer ? Or should one use shared_ptr
| for every cases ?
|
| Thanks in advance for your remarks !

There may be cases in your code where you do not want to have the
semantics of more than one smart pointer owning a pointer. For
example, consider:

struct B {};

struct A
{
public:
...
void add(B*);
...
private:
std::vector<B*> data_;
};

Here, A holds a vector of (heap-based) pointers to B, and has a
function to add a dynamically allocated pointer to the internal vector.
A first try at implementing this might be:

void
A::add(B* b)
{
data_.push_back(b); // Not good!
}

The problem with this implementation is that vector::push_back may
throw an exception. If it does, then b is leaked! The careful
programmer will make sure that add() assumes ownership of b no matter
what. auto_ptr can be used to easily implement this:

void
A::add(B* b)
{
std::auto_ptr<B> ap(b);
data_.push_back(b);
ap.release();
}

First add() assumes ownership of b by putting it into a local auto_ptr.
This auto_ptr constructor will not throw. Then the pointer is
push_back'd into the vector. If this operation throws, then b will be
deleted by the auto_ptr. If the push_back succeeds, then ownership of
b is transferred from the local auto_ptr, to A with the ap.release()
statement. Now A's copy constructor, assignment and destructor are
responsible for managing b's lifetime.

This enables idioms such as:

a.add(new B);

If A::add() did not assume ownership of its pointer even under
exceptional conditions, then there would be no way for client code to
recover in the above example.

It is true that shared_ptr could have done the job here. But
shared_ptr is overkill for this application (actually so is auto_ptr).
An auto_ptr constructor and destructor is /much/ cheaper than the
equivalent shared_ptr operations.
 
C

Cy Edmunds

SerGioGio said:
Hello !

When a ref. counted smart pointer (template) class is available (like
boost::shared_ptr), is there any (semantic) reason to still use
std::auto_ptr rather than this smart pointer ? Or should one use shared_ptr
for every cases ?

Thanks in advance for your remarks !

SerGioGio

If I had to upgrade software like this:

Fred *pfred = new Fred(...);
// use pfred here
delete pfred;

I would probably use std::auto_ptr. I don't use that style of programming
myself and so have little use for std::auto_ptr. I find the semantics of
this class so treacherous, particularly the part where the assignment
operation changes the objects on both sides (!), that I greatly prefer
boost::shared_ptr for general use.
 
A

Alexander Terekhov

Cy Edmunds wrote:
[...]
myself and so have little use for std::auto_ptr. I find the semantics of
this class so treacherous, particularly the part where the assignment
operation changes the objects on both sides (!), ....

Yeah. Ever heard of "Einstein-Podolsky-Rosen correlation"? Quantum
mechanics, you know.

regards,
alexander.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top