Idiomatic use of std::auto_ptr or only use shared_ptr?
Asked Answered
R

5

19

Now that shared_ptr is in tr1, what do you think should happen to the use of std::auto_ptr? They both have different use cases, but all use cases of auto_ptr can be solved with shared_ptr, too. Will you abandon auto_ptr or continue to use it in cases where you want to express explicitly that only one class has ownership at any given point?

My take is that using auto_ptr can add clarity to code, precisely by adding nuance and an indication of the design of the code, but on the other hand, it add yet another subtle issue when training new programmers: they need to understand smart pointers and the fine details of how they work. When you use only one smart pointer everywhere, you can just lay down a rule 'wrap all pointers in shared_ptr' and be done with it.

What's your take on this?

Rebbeccarebe answered 13/10, 2008 at 8:56 Comment(0)
M
13

To provide a little more ammunition to the 'avoid std::auto_ptr' camp: auto_ptr is being deprecated in the next standard (C++0x). I think this alone is good enough ammunition for any argument to use something else.

However, as Konrad Rudolph mentioned, the default replacement for auto_ptr should probably be boost::scoped_ptr. The semantics of scoped_ptr more closely match those of auto_ptr and it is intended for similar uses. The next C++09 standard will have something similar called unique_ptr.

However, using shared_ptr anywhere that scoped_ptr should be used will not break anything, it'll just add a very slight bit of inefficiency to deal with the reference count if the object is never actually going to be shared. So for private member pointers that will never be handed out to another object - use scoped_ptr. If the pointer will be handed out to something else (this includes using them in containers or if all you want to do is transfer ownership and not keep or share it) - use shared_ptr.

Maltese answered 13/10, 2008 at 15:52 Comment(2)
Mike, unfortunately there is no tr1::scoped_ptr. Apparently they wanted to keep it simple. I don't know about the status in TR2 but since the next standard will introduce the unique_ptr instead, I doubt there will be a scoped_ptr.Prime
Accepted this one, didn't know auto_ptr was being deprecated. Like you say, that alone is an authoritative reason to not use it; I liked MSalters' example of 'relinquish ownership semantics', though.Rebbeccarebe
B
28

auto_ptr is nice in signatures, too. When a function takes an auto_ptr<T> by value, it means it will consume the T. If a function returns an auto_ptr<T>, it's clear that it relinquishes ownership. This can communicate your intents about the lifetime.

On the other hand, using scoped_ptr<T> implies that you don't want to care about the lifetime of the T. This also implies you can use it in more places. Both smart pointers are valid choices, you can certainly have both in a single program.

Busch answered 13/10, 2008 at 9:34 Comment(1)
Best description of what auto_ptr should be used for.Edwardoedwards
M
13

To provide a little more ammunition to the 'avoid std::auto_ptr' camp: auto_ptr is being deprecated in the next standard (C++0x). I think this alone is good enough ammunition for any argument to use something else.

However, as Konrad Rudolph mentioned, the default replacement for auto_ptr should probably be boost::scoped_ptr. The semantics of scoped_ptr more closely match those of auto_ptr and it is intended for similar uses. The next C++09 standard will have something similar called unique_ptr.

However, using shared_ptr anywhere that scoped_ptr should be used will not break anything, it'll just add a very slight bit of inefficiency to deal with the reference count if the object is never actually going to be shared. So for private member pointers that will never be handed out to another object - use scoped_ptr. If the pointer will be handed out to something else (this includes using them in containers or if all you want to do is transfer ownership and not keep or share it) - use shared_ptr.

Maltese answered 13/10, 2008 at 15:52 Comment(2)
Mike, unfortunately there is no tr1::scoped_ptr. Apparently they wanted to keep it simple. I don't know about the status in TR2 but since the next standard will introduce the unique_ptr instead, I doubt there will be a scoped_ptr.Prime
Accepted this one, didn't know auto_ptr was being deprecated. Like you say, that alone is an authoritative reason to not use it; I liked MSalters' example of 'relinquish ownership semantics', though.Rebbeccarebe
S
11

"Use shared_ptr everywhere" is a good default rule, and certainly a good starting point for teaching people about responsible use of smart pointers. However, it's not always the best choice.

If you don't need shared ownership, shared_ptr is overkill: it has to allocate a separate memory block for the reference count, which can impact performance, and it is less clear documentation-wise.

Personally, I use std::auto_ptr in many places where boost::scoped_ptr would also suffice: e.g. holding a heap-allocated object before ownership is transferred elsewhere, where the intervening operations might throw.

C++0x will have std::unique_ptr to complement std::shared_ptr as a better alternative to std::auto_ptr. When it becomes widely available I'll start using that.

Silvanus answered 13/10, 2008 at 9:33 Comment(0)
P
5

I believe that it's best-practice is to substitute all uses of std::auto_ptr by boost::scoped_ptr unless std::tr1::shared_ptr meets the requirements better, if you don't mind using Boost. On the other hand, it was surely intentional that scoped_ptr wasn't included in TR1.

Prime answered 13/10, 2008 at 9:20 Comment(4)
scoped_ptr has its use, namely single-ownership that doesn't require transfer. In those cases, it should take the place of auto_ptr. However, where single-ownership, transfer semantics is appropriate, auto_ptr should still be used. :-)Underwaist
What makes scoped_ptr better than a const auto_ptr? There is an item about auto_ptr in Exceptional C++ and a paragraph especially about const auto_ptr; from reading about scoped_ptr I don't see any advantages over a const auto_ptr.Rebbeccarebe
auto_ptr may yield ownership. Often, this isn't required. Basically, a scoped_ptr implements just RAII for an arbitrary pointer in a given block.Prime
const auto_ptr can't yield ownership. The copy constructor takes a non-const reference. I would still use scoped_ptr though as I think it conveys the intent a little bit better.Fukien
U
3

I believe that "wrap all pointers in shared_ptr" should indeed be the default mode, and is suitable advice to give to your junior coders. However, in the special ownership cases that you mentioned, auto_ptr is indeed more appropriate and its use should be encouraged under such circumstances.

Underwaist answered 13/10, 2008 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.