【问题标题】:What's with unique_ptr::get() instead of &*?unique_ptr::get() 而不是 &* 有什么用?
【发布时间】:2015-10-30 17:24:12
【问题描述】:

我正在使用unique_ptr 管理一些资源,以便在各种情况下安全销毁等。

void do_something(BLOB* b);
unique_ptr<BLOB> b(new_BLOB(20));

&amp;* 比 get 差很多吗?例如

do_something(&*b);

do_someting(b.get());

两者似乎都有效。

【问题讨论】:

  • 这与使用 &amp;* 和迭代器非常相似。
  • “更糟”是主观术语,在什么意义上更糟?

标签: c++ pointers smart-pointers unique-ptr


【解决方案1】:

如果unique_ptr 不拥有任何内存,则std::unique_ptroperator* 具有未定义的行为,其中get() 将返回nullptr

如果unique_ptr 可能为空,我建议使用get(),否则没有区别。

【讨论】:

    【解决方案2】:

    &amp;*b 不一定等同于b.get()。为了确保收到指向托管对象的指针,您需要使用get()。 有两个原因:

    • 在不管理任何对象的 unique_ptr 上调用 operator* 是未定义的行为
    • T 类型的托管对象可能会重载 operator&amp;,因此您可能无法收到指向 T 的有效指针。

    标准定义了operator*的行为std::unique_ptr

    typename add_lvalue_reference&lt;T&gt;::type operator*() const;

    1. 要求:get() != nullptr

    2. 返回:*get()

    因此,如果get() 返回nullptr,则不允许应用operator*(来自&amp;*)。

    如果存在,您将获得托管对象中任何重载的operator&amp; 的返回值。这可以通过使用std::addressof 来规避,但未定义的行为问题仍然存在。

    std::unique_ptr&lt;T&gt;::get() 将为您提供托管对象的地址,如果没有托管对象,则为nullptr。使用get() 更安全,而且您有一个可预测的结果。

    【讨论】:

      【解决方案3】:

      正如其他答案所指出的,如果 unique_ptr 不管理任何对象,则使用 &amp;* 会导致未定义的行为。

      对于unique_ptr 管理指针的情况,在大多数情况下,

      do_something(&*b);
      

      等价于

      do_someting(b.get());
      

      唯一可能得到不同结果的情况是BLOB 有一个operator&amp; 重载,它返回的指针与对象的地址不同。

      【讨论】:

        【解决方案4】:

        这确实是一个基于意见的问题。

        我碰巧认为&amp;*ptr 看起来很丑,读者不清楚为什么会这样写。但它确实具有适用于智能指针和常规指针的优点。

        【讨论】:

        • 这个优势也可以通过模板特化或类型特征来实现。
        • 虽然您认为这是一个基于意见的问题,但您为 &* 提供了一个很好的技术理由
        猜你喜欢
        • 2012-06-03
        • 2022-11-18
        • 2017-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多