auto_ptr

Started by
11 comments, last by MaulingMonkey 18 years, 3 months ago
I decided to finally break down and learn the STL in detail. So I'm wondering people's opinion on using auto_ptr. Specifically just making every pointer an auto_ptr unless some other type of smart pointer is more appropriate. Particularly whether it wouldn't be better to limit it to scenerios where a single delete statement wouldn't handle freeing the object properly or for which it might not be clear who is responsible for freeing the object.
Keys to success: Ability, ambition and opportunity.
Advertisement
Go get a copy of accelerated C++ by Koenig and Moo.

You will learn all of the STL you need.

As far as pointers go, if you do c++ properly you should never need to call new or delete. Between the container classes and the auto_ptr type (and boost's smart pointers), you should be fully covered.

Also, see this list. As it says, read them mostly in order. You might need something down the list before you get to it.

frob.
The drawback with auto_ptr is that you cannot safely put it into an stl container. The advantage of using auto_ptr is that it saves you in situation where exception handling code might bypass the code to delete the pointer. It provides a very simple but effective safety net. It's got it's uses, but it's not the magic bullet.
I'll second Koenig&Moo -- it's the only introductory C++ book that I know that teaches you to code C++ and not C-with-classes.

Quote:Original post by frob
As far as pointers go, if you do c++ properly you should never need to call new or delete. Between the container classes and the auto_ptr type (and boost's smart pointers), you should be fully covered.


New is still nessesary for polymorphism and non-auto lifetimes, but agreed -- you should never be calling delete ( or fclose() or closesocket() or ... ) except in the destructor of a RAII class.

Once nice use of auto_ptr is returning from a clone() function -- if they ignore it or don't explicitly do something stupid, then it wont leak. I also like it for accepting pointers, because a function taking an auto_ptr by value makes it very clear that you're taking over the lifetime management of that object.

As for containers of polymorphic objects, also consider The Boost Pointer Container Library. You can treat a ptr_vector<Base> almost liek a vector<Base&> -- the extra dereference ( an implementation detail of storing pointers for polymorphism ) is done for you. It also deletes and clones where nessesary so there's no reference counting needed.

Of course, if you're keeping handles to the objects in your container, you might still want a std::container of shared_ptrs so you can have weak_ptr handles.
Quote:Original post by LilBudyWizer
Particularly whether it wouldn't be better to limit it to scenerios where a single delete statement wouldn't handle freeing the object properly or for which it might not be clear who is responsible for freeing the object.


I don't use delete anymore, I exclusively use boost::scoped_ptr for when I would do new/code/delete, and boost::shared_ptr when the pointer needs to be passed around or stored. std::auto_ptr has it's places but I don't use it unless it is for some reason difficult to use the boost ptrs, or if a dependency on boost is unacceptable.

Similarly I use boost::*_array and boost::mutex::scoped_lock. Basically anywhere you have to call something at the beginning of a function and at the end, use a "smart" or scoped solution - it's mostly exception-safe and will free you to insert return's anywhere in the function.
I often use std::auto_ptr as the return value from functions (though Washu dislikes that practice). Otherwise mostly I use boost::shared_ptr.
Quote:Original post by LilBudyWizer
I decided to finally break down and learn the STL in detail. So I'm wondering people's opinion on using auto_ptr. Specifically just making every pointer an auto_ptr unless some other type of smart pointer is more appropriate. Particularly whether it wouldn't be better to limit it to scenerios where a single delete statement wouldn't handle freeing the object properly or for which it might not be clear who is responsible for freeing the object.


Generally speaking, some other pointer type is more appropriate.

The best use of std::auto_ptr is when you have a member of a class that is a pointer. For example,
#include <memory>class X;class C{public:  void f() { m_x = std::auto_ptr<X>(new X); }private:  std::auto_ptr<x> m_x;};


This has the advantage that you don't need to write your own destructor to delete m_x, the default destructor will do the right thing, and the compiler will not let you accidentally copy the object, resulting in a double deletion (the bane of pointer members). You will have to write your own copy constructor and operator= if you want to copy such objects.

Using std::auto_ptr this was is very similar to having members that are references, except that references muct be bound at object construction time, whereas std:auto_ptrs can be set later (after, say, reading your configuration file).

--smw

Stephen M. Webb
Professional Free Software Developer

For general use I think the Boost smart pointer library is much better than std::auto_ptr. Of particular interest are both the enable_shared_from_this class and the ability to specify custom deleters for your pointer. This latter is particularly useful. For example, you can keep a COM interface pointer inside a shared_ptr, and have it call the Release() member function whenever it goes out of scope. I find this a remarkably convenient way of dealing with COM objects because I absolutely hate their manual reference counting. Between boost::shared_ptr and boost::scoped_ptr, the only real use for std::auto_ptr is for when you want to enforce single ownership but not noncopyable semantics, which really isn't that often in my experience. I think its best use is mentioned up above by me22 in that passing a std::auto_ptr to a class makes it very clear that the class intends to take over lifetime ownership of that memory.

Overall though, I'd definitely recommend using smart pointers wherever possible. I, like some who have posted before me, almost never actually use delete anymore when I'm programming in C++.
Playing with it a bit and reading the posts I have to conclude it isn't a good "none of the above" smart pointer.

I don't know to what degree Boost is an option. BCB6 is supported, but as soon as they release it I'm upgrading to BDS2006. It just seems it would make most sense to wait until Boost actually has the workarounds specific to BDS2006 incorporated since I have no code currently using it. Particularly since as soon as BDS2006 arrives I have higher priority things to do. I'm a long ways out from starting an engine in earnst so Boost doesn't seem a high priority for experimental code. By the time I'm ready there will most likely be a patch to BDS2006 and an update to Boost with workarounds specific to BDS2006 incorporated.
Keys to success: Ability, ambition and opportunity.
Quote:Original post by Bregma

...
#include <memory>

class X;

class C
{
public:
void f() { m_x = std::auto_ptr<X>(new X); }

private:
std::auto_ptr<x> m_x;
};


This has the advantage that you don't need to write your own destructor to delete m_x, the default destructor will do the right thing, ...


No it won't, in this case. It will ONLY be deleted properly if the class has a non-default destructor. Otherwise, the forward declaration in the header is not enough information for the compiler to create a destructor of the member object. I got bit by this a long time ago. Won't make that mistake again.

For another interesting thing you can do with pointer wrappers, you can look at: http://www.codeproject.com/cpp/TwoThirdsPimpl.asp.

David

This topic is closed to new replies.

Advertisement