3 Answers
3

1) Does this mean that all classes that have this behavior should not
be used in containers?

Yes indeed, because that is not correct copying behaviour, since the copy is not equal to the source afterwards but destroys the source. This is kind of a broken implementation of move-semantics before C++11, required for the strict unique ownership semantics of std::auto_ptr.

2) what sort of containers can you use?

The real answer is actually, that classes having this behaviour (a copy constructor/assignment destroying its source) should just not exist. And fortunately this is not needed anymore nowadays, since C++11 has proper move-semantics, which realize exactly this destructive copy but in a safe way (simply said, only when the source is really not needed anymore).

Therefore std::auto_ptr is deprecated and should not be used anymore. It has been replaced by std::unique_ptr which is movable but not copyable. But since C++11 containers rather move their elements than copy when appropriate, a std::unique_ptr can be used perfectly inside of standard containers. You just cannot copy the container or fill it with a single object which would require copies of std::unique_ptrs, but those operations should not work anyway, since they are conceptually wrong for unique ownership semantics.

And as a side note, if you actually chose std:auto_ptr for a reason, that is you want unique ownership semantics, then a std::shared_ptr (as suggested by other answers) is plain wrong since it exhibits shared ownership. std::unique_ptr is today's std::auto_ptr. Never spam std::shared_ptrs where std::unique_ptrs (or even raw pointers, but from your question I rule that option out) are appropriate.

Unless you have to. Practically speaking, most programmers can't use C++11 yet, and if they need pointers to owned objects in a container (which should be very, very rare), then boost::shared_ptr is about the only game in town.
–
James KanzeSep 13 '12 at 9:17

Auto pointer has a very strict ownership: it and only it is responsible for the lifetime of the object it points at. If you copy an auto_ptr, you lose the reference to what it pointed at.

The problem is in the way STL containers do their stuff. For example, when you are adding an element, the container might expand to get more memory, which leads to copying all the values to the new memory, which, itself, leads to losing the auto_ptrs.

I think that associative containers might not copy themselves entirely when they allocate additional memory, but I'm absolutely not sure, if someone can confirm it, please post a comment, or just edit my answer. Anyway, you'd better not risk it.

Also note that Auto_ptr is deprecated since C++0x, it is advised to use unique_ptr instead. In your case, std::shared_ptr will probably do the trick, unless you really need unique ownership for those objects of yours.

"In your case, std::shared_ptr will probably do the trick" - No it won't (at least not if he chose std::auto_ptr for a reason), since std::shared_ptr manages shared ownership, which is conceptually wrong when working with unique ownership. No need to spam shared_ptrs where unique_ptrs are appropriate (and they can be used in containers, since C++11 containers rather move than copy).
–
Christian RauSep 13 '12 at 8:27

@Chris, ahh, that's a nice point, I totally forgot that the OP might need unique ownership, and was talking just about the containers... I'll edit it, thanks.
–
SingerOfTheFallSep 13 '12 at 8:29

2

No, unique_ptr should be the default smart pointer- not shared_ptr.
–
PuppySep 13 '12 at 8:39

In your example insertion, doesn't a[2] get set to NULL in the first copy (and likewise a[1] in the second). So there shouldn't be anything deleted incorrectly here and it should actually work.
–
Christian RauSep 13 '12 at 9:57

you are right. I have removed the incorrect part until I find time to describe the correct scenario.
–
Zdeslav VojkovicSep 13 '12 at 11:08