【问题标题】:Letting go of auto_ptr放开 auto_ptr
【发布时间】:2011-01-26 07:45:23
【问题描述】:

有时,对于稍纵即逝的时刻,我认为 auto_ptr 很酷。但大多数时候,我认识到有更简单的技术使它变得无关紧要。例如,如果我想自动释放一个对象,即使抛出异常,我也可以新建对象并分配给 auto_ptr。很酷!但我可以更轻松地将我的对象创建为局部变量,并让堆栈来处理它(呃!)。

因此,当我发现google C++ coding standards 禁止使用 auto_ptr 时,我并没有太惊讶。 Google 声明应该使用 scoped_ptr(如果需要智能指针)。

我想知道是否有人可以根据我的经验给出充分的理由说明 auto_ptr 何时是最好或最简单的东西。如果没有,那么我想我会禁止自己使用它(按照谷歌的引导)。

更新:对于那些表示担忧的人,不,我没有采用谷歌标准。例如,根据谷歌的建议,我同意应该激活异常处理。我也喜欢使用预处理器宏,比如我制作的printable enum。让我印象深刻的只是 auto_ptr 主题。

update2:原来我的回答来自下面的两个响应者和一个note from Wikipedia。首先,Herb Sutter 确实展示了一个有效的用途(源-汇成语和生命周期关联的对象组合)。其次,有些商店 TR1 和 boost 不可用或被禁止,只允许使用 C++03。第三,根据 Wikipedia,C++0x 规范正在弃用 auto_ptr 并将其替换为 unique_ptr。所以我的回答是:如果我可以使用 unique_ptr(在考虑的所有平台上),则使用 auto_ptr 用于 Sutter 描述的情况。

【问题讨论】:

  • 谷歌风格指南也禁止例外。我们会禁止例外,因为有人弄错了,谷歌风格指南禁止了它们吗?没有。
  • 不要遵循 Google 的指导方针,一般来说,它们是针对它们的,并且需要与其庞大的 C 代码库集成。 (虽然有很多理由不使用auto_ptr)。

标签: c++ coding-style smart-pointers auto-ptr


【解决方案1】:

当您需要一个作用域或唯一指针并且您在严格的 C++03 环境中工作而无法访问 tr1 实现或 boost 时,这是最简单的使用方法。

【讨论】:

    【解决方案2】:

    Herb Sutter 可以帮助您解决这个问题:http://www.drdobbs.com/184403837

    【讨论】:

      【解决方案3】:

      虽然禁止auto_ptr 看起来很有吸引力,但有一个问题:

      template <typename T>
      some_smart_ptr<T> create();
      

      您将用什么替换 some_smart_ptr 占位符?

      通用答案shared_ptr,只有在所有权真正共享时才值得,如果函数授予调用者对资源的独占所有权,它充其量是误导(就我而言,这是过早悲观的典型案例我很担心)。

      另一方面,在 C++03 中,没有其他形式的智能指针可以提供:如果没有移动语义,就不可能在这里提供我们想要的东西。 auto_ptr 或裸指针是两个逻辑竞争者。但是,如果调用者粗心,裸指针会使您面临泄漏的风险。

      对于 C++0x,unique_ptr 在任何情况下都可以方便地替换 auto_ptr

      【讨论】:

        【解决方案4】:

        std::auto_ptr 仍然具有指针语义,因此不能替代自动(非指针)变量。特别是,std::auto_ptr 支持多态性和重新分配。使用堆栈变量,您可以将引用用于多态性,但引用不允许重新分配。

        有时std::auto_ptr 会很好。例如,用于实现 pimpl。诚然,在绝大多数情况下,boost 的智能指针库为智能指针提供了更好的选择。但是现在std::auto_ptr 是一个标准的解决方案,而 boost 的智能指针不是。

        【讨论】:

          【解决方案5】:

          使用 auto_ptr 作为函数返回值,您将享受没有复制开销并且永远不会发生内存泄漏。 std::auto_ptr&lt;obj&gt; foo() 可以安全地在 { foo(); } 中调用,而 obj *foo() 不能。 boost::shared_ptr 可以解决这个问题,但是开销更高。

          此外,由于内存限制,某些对象无法在堆栈上创建:线程堆栈相对较小。但是 boost::scoped_ptr 在这种情况下会更好,因为它不会被意外释放。

          【讨论】:

            【解决方案6】:

            其中一个原因是scoped_ptr 是不可复制的,因此使用起来更安全,也更难出错。 auto_ptr 允许所有权转移(例如,通过将另一个 auto_ptr 作为构造函数参数传递给它)。如果您需要考虑诸如转让所有权之类的事情,那么您最好使用像shared_ptr 这样的智能指针。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-05
              • 1970-01-01
              • 2011-03-27
              • 1970-01-01
              相关资源
              最近更新 更多