| 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:
ush_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.