问题
With the new standard coming (and parts already available in some compilers), the new type std::unique_ptr
is supposed to be a replacement for std::auto_ptr
.
Does their usage exactly overlap (so I can do a global find/replace on my code (not that I would do this, but if I did)) or should I be aware of some differences that are not apparent from reading the documentation?
Also if it is a direct replacement, why give it a new name rather than just improve the std::auto_ptr
?
回答1:
You cannot do a global find/replace because you can copy an auto_ptr
(with known consequences), but a unique_ptr
can only be moved. Anything that looks like
std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p;
will have to become at least like this
std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);
As for other differences, unique_ptr
can handle arrays correctly (it will call delete[]
, while auto_ptr
will attempt to call delete
.
回答2:
std::auto_ptr
and std::unique_ptr
are incompatible in someways and a drop in replacement in others. So, no find/replace isn't good enough. However, after a find/replace working through the compile errors should fix everything except weird corner cases. Most of the compile errors will require adding a std::move
.
- Function scope variable:
100% compatible, as long as you don't pass it by value to another function. - Return type:
not 100% compatible but 99% compatible doesn't seem wrong. - Function parameter by value:
100% compatible with one caveat,unique_ptr
s must be passed through astd::move
call. This one is simple as the compiler will complain if you don't get it right. - Function parameter by reference:
100% compatible. - Class member variable:
This one is tricky.std::auto_ptr
s copy semantics are evil. If the class disallows copying thenstd::unique_ptr
is a drop in replacement. However, if you tried to give the class reasonable copy semantics, you'll need to change thestd::auto_ptr
handling code. This is simple as the compiler will complain if you don't get it right. If you allowed copying of a class with astd::auto_ptr
member without any special code, then shame on you and good luck.
In summary, std::unique_ptr
is an unbroken std::auto_ptr
. It disallows at compile time behaviors that were often errors when using a std::auto_ptr
. So if you used std::auto_ptr
with the care it needed, switching to std::unique_ptr
should be simple. If you relied on std::auto_ptr
's odd behavior, then you need to refactor your code anyway.
回答3:
AFAIK, unique_ptr
is not a direct replacement. The major flaw that it fixes is the implicit transfer of ownership.
std::auto_ptr<int> a(new int(10)), b;
b = a; //implicitly transfers ownership
std::unique_ptr<int> a(new int(10)), b;
b = std::move(a); //ownership must be transferred explicitly
On the other hand, unique_ptr
will have completely new capabilities: they can be stored in containers.
回答4:
Herb Sutter has a nice explanation on GotW #89:
What’s the deal with auto_ptr? auto_ptr is most charitably characterized as a valiant attempt to create a unique_ptr before C++ had move semantics. auto_ptr is now deprecated, and should not be used in new code.
If you have auto_ptr in an existing code base, when you get a chance try doing a global search-and-replace of auto_ptr to unique_ptr; the vast majority of uses will work the same, and it might expose (as a compile-time error) or fix (silently) a bug or two you didn't know you had.
In other words, while a global search-and-replace may "break" your code temporarily, you should do it anyway: It may take some time to fix the compile errors, but will save you a lot more trouble in the long run.
来源:https://stackoverflow.com/questions/3451099/stdauto-ptr-to-stdunique-ptr