放弃 auto_ptr
有时候,在转瞬即逝的时刻,我认为 auto_ptr 很酷。但大多数时候我认识到有一些更简单的技术使它变得无关紧要。例如,如果我想自动释放一个对象,即使抛出异常,我也可以新建该对象并分配给 auto_ptr。非常酷!但我可以更轻松地将对象创建为局部变量,并让堆栈来处理它(废话!)。
因此,当我发现 Google C++ 编码标准禁止使用auto_ptr。 Google 指出应该使用scoped_ptr(如果需要智能指针)。
我想知道是否有人与我的经验相反,可以给出一个可靠的理由来说明 auto_ptr 何时是最好或最简单的使用方法。如果没有,那么我想我自己会禁止使用它(跟随谷歌的脚步)。
更新:对于那些表示担忧的人,我不会采用谷歌标准。例如,根据谷歌的建议,我同意应该激活异常处理。我也喜欢使用预处理器宏,例如我制作的 可打印枚举 。让我印象深刻的是 auto_ptr 主题。
update2:事实证明我的答案来自下面的两个回复者,以及来自维基百科的注释。首先,Herb Sutter 确实展示了一种有效的用法(源-汇习语和与生命周期相关的对象组合)。其次,有些商店TR1和boost不可用或被禁止,只允许使用C++03。第三,根据 Wikipedia,C++0x 规范正在弃用 auto_ptr 并将其替换为 unique_ptr。所以我的答案是:如果我可以使用 unique_ptr(在考虑的所有平台上),则使用 unique_ptr,否则对于 Sutter 描述的情况使用 auto_ptr。
Occasionally, for fleeting moments, I think auto_ptr is cool. But most of the time I recognize that there are much simpler techniques that make it irrelevant. For example, if I want to have an object freed automatically, even if an exception is thrown, I could new up the object and assign to an auto_ptr. Very cool! But I could have more easily created my object as a local variable, and let the stack take care of it (duh!).
Thus I was not too surprised when I found google C++ coding standards banning the use of auto_ptr. Google states that scoped_ptr should be used instead (if a smart pointer is needed).
I'd like to know if anyone, contrary to my experience, can give a solid reason(s) of when auto_ptr is the best or simplest thing to use. If not, then I suppose I will ban using it myself (following google's lead).
update: For those who expressed concern, no I am not adopting google standards. For example, against google advice, I agree exception-handling should be activated. I also like using preprocessor macros, such as the printable enum I made. It is just the auto_ptr topic that struck me.
update2: It turns out my answer comes from two of the responders below, and a note from Wikipedia. First, Herb Sutter did show a valid use (source-sink idiom and lifetime-linked object composition). Second, there are shops where TR1 and boost are not available or banned and only C++03 is allowed. Third, according to Wikipedia, the C++0x spec is deprecating auto_ptr and replacing it with unique_ptr. So my answer is: use unique_ptr if available to me (on all platforms in consideration) else use auto_ptr for the cases that Sutter depicts.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
当您需要作用域或唯一指针并且您在严格的 C++03 环境中工作而无法访问 tr1 实现或 boost 时,这是最简单的方法。
It's the simplest thing to use when you need a scoped or unique pointer and you are working in a strict C++03 environment with no access to a tr1 implementation or boost.
Herb Sutter 可以帮助您解决这一问题:http://www.drdobbs.com/184403837
Herb Sutter can help you out on this one: http://www.drdobbs.com/184403837
虽然禁止
auto_ptr
看起来很有吸引力,但有一个问题:您将用什么替换
some_smart_ptr
占位符?通用答案,
shared_ptr
,只有在所有权真正共享的情况下才值得,如果函数授予调用者对资源的独占所有权,那么它充其量只是误导(并且是过早悲观的典型情况)就我而言)。另一方面,在 C++03 中,没有其他形式的智能指针可以提供:如果没有移动语义,就不可能提供我们在这里想要的东西。
auto_ptr
或裸指针是两个逻辑竞争者。但是,如果调用者不小心,裸指针会让您面临泄漏的风险。对于 C++0x,
unique_ptr
在任何情况下都可以有利地替换auto_ptr
。While banning
auto_ptr
seems attractive, but there is one issue:What will you replace the
some_smart_ptr
placeholder with ?The generic answer,
shared_ptr
, is only worth it if the ownership is truly shared, if the function grants the caller exclusive ownership of the resources, it's misleading at best (and a typical case of premature pessimization as far as I am concerned).On the other hand, in C++03, no other form of smart pointer can deliver: it's impossible, without move semantics, to provide what we'd like here.
auto_ptr
or a naked pointer are the two logical contenders. But then a naked pointer exposes you to the risk of leaks if the caller is careless.With C++0x,
unique_ptr
advantageously replaceauto_ptr
in every situation.std::auto_ptr
仍然具有指针语义,因此自动(非指针)变量不能替代。特别是,std::auto_ptr 支持多态性和重新分配。对于堆栈变量,您可以使用引用来实现多态性,但引用不允许重新分配。有时 std::auto_ptr 就可以了。例如,用于实现 pimpl。确实,在绝大多数情况下,Boost 的智能指针库为智能指针提供了更好的选择。但现在 std::auto_ptr 是一个标准解决方案,而 boost 的智能指针则不是。
std::auto_ptr
still has pointer semantics, so automatic (non-pointer) variables aren't a substitute. In particular,std::auto_ptr
supports polymorphism and re-assignment. With stack variables you can use references for polymorphism, but references don't allow for re-assignment.Sometimes
std::auto_ptr
will do just fine. For example, for implementing a pimpl. True, in the vast majority of cases boost' smart pointer library offers better choices for a smart pointer. But right nowstd::auto_ptr
is a standard solution, whereas boost's smart pointers aren't.使用 auto_ptr 作为函数返回值,您将不会享受复制开销并且永远不会出现内存泄漏。
std::auto_ptr;可以在
而{ foo(); 中安全地调用 foo()
}obj *foo()
则不能。 boost::shared_ptr 可以解决这个问题,但开销更高。此外,由于内存限制,某些对象无法在堆栈上创建:线程堆栈相对较小。但 boost::scoped_ptr 在这种情况下更好,因为它不会被意外释放。
Using auto_ptr as function return value you will enjoy no copiyng overhead and never have memory leak.
std::auto_ptr<obj> foo()
can be safely called in{ foo(); }
whileobj *foo()
cannot. boost::shared_ptr can solve this, but with higher overhead.Also, some objects can't be created on stack because of memory constraints: thread stacks are relatively small. But boost::scoped_ptr is better in this case since it can't be accidentally released.
原因之一是
scoped_ptr
是不可复制的,因此使用起来更安全并且更难犯错误。auto_ptr
允许所有权转移(例如,通过将另一个auto_ptr
作为构造函数参数传递给它)。如果您需要考虑诸如转移所有权之类的事情,那么使用像shared_ptr
这样的智能指针可能会更好。Well one reason would be that
scoped_ptr
is non-copyable, so it's safer to use and harder to make mistakes with.auto_ptr
allows transfer of ownership (eg. by passing it anotherauto_ptr
as a constructor parameter). If you need to think things like transferring the ownership, the chances are you're better off with a smart pointer likeshared_ptr
.