【问题标题】:Idiomatic use of std::auto_ptr or only use shared_ptr?惯用 std::auto_ptr 还是只使用 shared_ptr?
【发布时间】:2010-09-16 20:35:53
【问题描述】:

现在shared_ptr 在tr1 中,您认为std::auto_ptr 的使用会发生什么?它们都有不同的用例,但auto_ptr 的所有用例也可以用shared_ptr 解决。你会放弃auto_ptr 还是在你想明确表示在任何给定点只有一个类拥有所有权的情况下继续使用它?

我的看法是,使用 auto_ptr 可以增加代码的清晰度,正是通过添加细微差别和代码设计的指示,但另一方面,它在培训新程序员时增加了另一个微妙的问题:他们需要了解智能指针以及它们如何工作的细节。当您在任何地方只使用一个智能指针时,您只需制定一条规则“将所有指针包装在 shared_ptr 中”并完成它。

您对此有何看法?

【问题讨论】:

    标签: c++ coding-style smart-pointers tr1


    【解决方案1】:

    auto_ptr 在签名方面也很不错。当一个函数按值获取auto_ptr<T> 时,这意味着它将消耗T。如果一个函数返回一个auto_ptr<T>,很明显它放弃了所有权。这可以传达您关于生命周期的意图。

    另一方面,使用scoped_ptr<T> 意味着您不想关心T 的生命周期。这也意味着您可以在更多地方使用它。两个智能指针都是有效的选择,你当然可以在一个程序中同时拥有这两个。

    【讨论】:

    • 对 auto_ptr 用途的最佳描述。
    【解决方案2】:

    为“避免std::auto_ptr”阵营提供更多弹药:auto_ptr 将在下一个标准 (C++0x) 中弃用。我认为仅此一项就足以让任何论点使用其他东西。

    但是,正如Konrad Rudolph 所提到的,auto_ptr 的默认替换可能应该是boost::scoped_ptrscoped_ptr 的语义与auto_ptr 的语义更接近,并且旨在用于类似用途。下一个 C++09 标准将有类似的东西,称为 unique_ptr。

    但是,在任何应该使用scoped_ptr 的地方使用shared_ptr 不会破坏任何东西,如果对象实际上永远不会被共享,它只会增加一点处理引用计数的低效率。因此,对于永远不会分发给另一个对象的私有成员指针 - 使用scoped_ptr。如果指针将被分发给其他东西(这包括在容器中使用它们,或者如果您只想转移所有权而不是保留或共享它) - 使用shared_ptr

    【讨论】:

    • 迈克,很遗憾没有tr1::scoped_ptr。显然他们想保持简单。我不知道 TR2 中的状态,但由于下一个标准将引入unique_ptr,我怀疑会有scoped_ptr
    • 接受了这个,不知道 auto_ptr 被弃用了。就像您说的那样,仅此一项就是不使用它的权威理由;不过,我喜欢 MSalters 的“放弃所有权语义”示例。
    【解决方案3】:

    “在任何地方使用shared_ptr”是一个很好的默认规则,当然也是教导人们负责任地使用智能指针的一个很好的起点。然而,它并不总是最好的选择。

    如果您不需要共享所有权,shared_ptr 就大材小用了:它必须为引用计数分配一个单独的内存块,这会影响性能,而且在文档方面不太清楚。

    就个人而言,我在许多boost::scoped_ptr 也足够的地方使用std::auto_ptr:例如在所有权转移到其他地方之前持有一个堆分配的对象,干预操作可能会抛出。

    C++0x 将使用std::unique_ptr 来补充std::shared_ptr,作为std::auto_ptr 的更好替代品。当它变得广泛可用时,我将开始使用它。

    【讨论】:

      【解决方案4】:

      我认为最好的做法是用boost::scoped_ptr 替换std::auto_ptr 的所有用法,除非std::tr1::shared_ptr 更好地满足要求,如果您不介意使用 Boost。另一方面,scoped_ptr 未包含在 TR1 中肯定是故意的。

      【讨论】:

      • scoped_ptr 有它的用途,即不需要转让的单一所有权。在这些情况下,它应该代替 auto_ptr。但是,在适合单一所有权转移语义的情况下,仍应使用 auto_ptr。 :-)
      • 是什么让 scoped_ptr 比 const auto_ptr 更好?在 Exceptional C++ 中有一个关于 auto_ptr 的项目和一个特别是关于 const auto_ptr 的段落;通过阅读有关 scoped_ptr 的内容,我没有看到比 const auto_ptr 有任何优势。
      • auto_ptr 可能会产生所有权。通常,这不是必需的。基本上,scoped_ptr 只为给定块中的任意指针实现 RAII。
      • const auto_ptr 不能产生所有权。复制构造函数采用非常量引用。我仍然会使用 scoped_ptr,因为我认为它可以更好地传达意图。
      【解决方案5】:

      我相信“将所有指针包装在shared_ptr”确实应该是默认模式,并且是给初级程序员的合适建议。但是,在您提到的特殊所有权情况下,auto_ptr 确实更合适,应该鼓励在这种情况下使用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-11
        • 2010-09-23
        • 2010-11-16
        • 2013-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-05
        相关资源
        最近更新 更多