【问题标题】:Convert Object to std::unique_ptr将对象转换为 std::unique_ptr
【发布时间】:2012-12-11 15:00:42
【问题描述】:

我有一个简单的菜鸟问题,我找不到答案:

在 C++ 中如何转换常规对象

int i;

变成std::unique_ptr?

std::unique_ptr<int> iptr = &i; //invalid
std::unique_ptr<int> iptr = static_cast<std::unique_ptr<int>>(&i); //invalid

谢谢。

【问题讨论】:

    标签: c++ pointers type-conversion


    【解决方案1】:

    我相信这会奏效:

    int i;
    auto deleter = [](int *ptr){};
    std::unique_ptr<int, decltype(deleter)> iptr(&i, deleter);
    

    您必须提供一个什么都不做的自定义删除器。默认删除器无法删除不是由new 分配的自动变量。 (然而,这违背了使用智能指针的目的,但表明它是可能的)。

    【讨论】:

      【解决方案2】:

      当 unique_ptr 被销毁时会发生什么?或者相反,当变量超出范围时?其实没有意义

      【讨论】:

        【解决方案3】:

        你没有。 i 不是动态分配的,所以不需要删除。如果您将智能指针包裹在其地址周围,它会在某个时候执行delete &amp;i 并给您未定义的行为。您应该只将您拥有的 newed 包装在智能指针中,如下所示:

        std::unique_ptr<int> ptr(new int(5));
        

        智能指针的全部意义在于它为您管理动态分配对象的生命周期。 i 具有自动存储持续时间,因此将在其范围结束时被销毁。你不需要任何东西来帮助你。

        【讨论】:

          【解决方案4】:

          你没有。 delete 无法删除该对象,这正是unique_ptr 要做的事情。你需要

          auto iptr = make_unique<int>();
          

          在这里,我们将 make_unique 定义为与 make_shared 相同的实用函数,它本应是标准的,但不幸的是被忽略了。下面是简单的实现:

          template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) {
              return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
          }
          

          【讨论】:

          • 虽然为了完整性,该功能会很好,但我认为它并没有被忽视,因为不需要。请记住,make_shared 解决了一次分配两个对象的问题(没有等效的构造函数),而 unique_ptr 根本不需要这个(它的设计开销为零)。
          • 这不是真的。如果在一个函数调用中构造两个 unique_ptrs 仍然存在异常不安全性,例如 make_unique 保存的。
          • 你不能通过直接创建 unique_ptr 来避免这种情况吗? func( unique_ptr&lt;T&gt;(new T), unique_ptr&lt;U&gt;(new U) )
          • 不,它仍然不安全。
          猜你喜欢
          • 2014-03-27
          • 2020-06-20
          • 2018-12-15
          • 2021-01-17
          • 2018-12-29
          • 2015-05-16
          • 2017-04-22
          • 1970-01-01
          • 2021-02-18
          相关资源
          最近更新 更多