0

In our large project we have a lot class with the following typedef's:

class Foo
{
  public:
    typedef std::auto_ptr<Foo> Ptr;
    typedef boost::shared_ptr<Foo> Ref;
  ...
};
...
Foo::Ref foo(new Foo);
...
doBar(foo);
...

The using of them is very convenient. But I doubt if auto_ptr is semantically close to Ptr and shared_ptr is the same as ref? Or should auto_ptr be used explicitly since it has "ownership transfer" semantics?

Thanks,

barankin
  • 1,853
  • 2
  • 12
  • 16

5 Answers5

2

std::auto_ptr has ownership transfer semantics, but it's quite broken. If you can use boost::shared_ptr, then you should use boost::unique_ptr instead of std::auto_ptr, since it does what one would expect. It transfers ownership and makes the previous instance invalid, which std::auto_ptr doesn't.

Even better, if you can use C++11, then swap to std::unique_ptr and std::shared_ptr.

Johann Gerell
  • 24,991
  • 10
  • 72
  • 122
  • 2
    `std::auto_ptr` isn't broken. As specified, it's overly complex, but it works well for what it was designed for, and is certainly more useful than `boost::shared_ptr`. – James Kanze Jan 31 '12 at 08:42
1

You shouldn't use std::auto_ptr, its deprecated and I consider it dangerous, even more so when you hide it behind such a generic typedef as Ptr.

I don't think it makes any sense to called shared_ptrRef, in this case it is more Ptr than auto_ptr.

EDIT: I consider it dangerous because you can easily misuse it, even when you fully understand its workings, you can accidentally misuse it, especially when hiding it behind a typedef. A good class should be easy to use right and should be difficult to misuse. Especially with the advent of unique_ptr I can't see any useful scenario for auto_ptr.

ronag
  • 49,529
  • 25
  • 126
  • 221
  • Who considers `std::auto_ptr` dangerous? – James Kanze Jan 31 '12 at 08:43
  • James Kanze: I do. Edited the answer. – ronag Jan 31 '12 at 08:51
  • How does a language feature(`auto_ptr` in this case) which is just difficult for most people to understand and use wisely become *dangerous*, I think `auto_ptr` is rather very useful if used wisely.You should probably state *`auto_ptr` usage is dangerous if you don't understand how it works.* – Alok Save Jan 31 '12 at 08:55
  • @phresnel That's true for most of the standard library:-): iterators, iostream manipulators, `streambuf` etc. That doesn't mean *dangerous*, however. When you need the semantics of `std::auto_ptr`, there are very few alternatives, and it works well. I've used it in almost all applications since it has become stable, and I've yet to see it cause problems for any maintenance programmer. – James Kanze Jan 31 '12 at 08:57
  • Als: If it wasn't dangerous and useful, why would they deprecate it? I don't know of any single case where ´auto_ptr´ is useful. When is ´auto_ptr´ useful according to you? – ronag Jan 31 '12 at 08:58
  • Now I'm getting curious, when do you guys find `auto_ptr` useful over the standard smart-pointers, `shared_ptr` and `unique_ptr`? – ronag Jan 31 '12 at 09:00
  • 2
    @ronag: `std::auto_ptr` is deprecated because `std::unique_ptr` implements the same contract while making it more flexible without compromising the integrity: `std::unique_ptr` can be move while `std::auto_ptr` cannot. The reason for this is the absence of rvalue reference support in C++2003. When use of rvalue references is an option, `std::unique_ptr` is the better choice. – Dietmar Kühl Jan 31 '12 at 09:22
  • I don't think so: there is nothing wring with using`std::auto_ptr` in C++2003 code which is, realistically, still the vast majority of the production code. Also, replacing `std::auto_ptr` with some form of shared pointer would be outright wrong: the latter enforces a memory management scheme. – Dietmar Kühl Jan 31 '12 at 09:51
  • @DietmarKühl: In the C++03 case I would suggest `boost::scoped_ptr`, possibly with `boost::move` (if support have been added to `scoped_ptr`?, otherwise roll your own). If you don't have boost I would suggest you roll your own. I can agree that `auto_ptr` is useful when you are using C++03 and want transfer of ownership (though I believe that is a rare use-case). – ronag Jan 31 '12 at 09:56
  • @ronag: returning objects allocated from spme sort of factory is a reasonably common use case. I don't have a lot use for scoped objects allocated on the heap: I prefer to have them allocated on the stack or directly embedded init the object. – Dietmar Kühl Jan 31 '12 at 10:26
0

auto_ptr is deprecated in C++11. You might want to stop using it and just use the shared_ptr. For shared_ptr, there is no ownership transfer on assignment, the number of references to the object is counted and the object is destroyed when the last pointer is destroyed.

devil
  • 1,829
  • 16
  • 23
0

I believe the order is just a nomenclature which someone used.
It probably should have been, ref for auto_ptr and ptr for shared_ptr, because:

References are immutable and hence cannot be made to refer to other object. auto_ptr has a similar(albeit remotely similar) semantics, transfer of ownership which means you would probably not want to assign a auto_ptr for the non-intuitive behavior it shows. The assigned object gains ownership while the object being assigned loses ownership.

On the Other hand shared_ptr has an reference counting mechanism which is similar(again remotely) to multiple pointers which can point to the same object. The ownership of the pointer rests with the shared_ptr itself and it gets deallocated as soon as there are no pointer instances referring to it.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

A lot depends on what they are being used for. And in the case of Ref, what people understand by it. In pre-standard days, I would often use a typedef to Ptr for my (invasive) reference counted pointer; the presence of such a typedef was, in fact, an indication that the type supported reference counting, and that it should always be dynamically allocated.

Both std::auto_ptr and boost::shared_ptr have very special semantics. I'd tend not to use typedefs for them, both because of the special semantics, and because (unlike the case of my invasive reference counted pointer) they are totally independent of the type pointed to. For any given type, you can use them or not, as the program logic requires. (Because of its particular semantics, I find a fair number of uses for std::auto_ptr. I tend to avoid boost::shared_ptr, however; it's rather dangerous.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329