【问题标题】:How to move unique_ptr to raw pointer?如何将 unique_ptr 移动到原始指针?
【发布时间】:2015-10-22 06:48:59
【问题描述】:

我有一个函数用于分配给定大小的缓冲区。缓冲区将在返回之前预处理/填充一些数据。此预处理可能返回 false 以表示此缓冲区未正确处理。所以我想在这个缓冲区上应用 RAII 以避免在没有delete[] 它的情况下提前返回。

通常我使用unique_ptr 来帮助我自动释放本地分配的对象。在这种情况下,我需要返回这个分配的对象(由unique_ptr 拥有)并将所有权转移给调用者。但是编译器抱怨我无法将unique_ptr<T[]> 转换为T* 而我std::move unique_ptr。看起来unique_ptr 只能移动到另一个unique_ptr 而不是原始指针。

有什么方法可以将所有权从unique_ptr 转移到raw pointer?或者只是unique_ptr 不适合这种情况?

bool PreProcess(int* v) { /* return nothing wrong? true: false; */ }

bool GetBuffer(int** ppRetBuf, int size)
{
    std::unique_ptr<int[]> buf(new (std::nothrow) int[size]());
    if(PreProcess(buf.get())
    {
        *ppRetBuf = std::move(buf); // Compiler complains:  
                                    // Error C2440 '=': cannot convert from 'std::unique_ptr<int [],std::default_delete<_Ty>>' to 'int *'
        return true;
    }
    return false; // No need to manually delete[] failure buffer
}

int main()
{
    int * buf = nullptr;
    GetBuffer(&buf, 100);
}

【问题讨论】:

  • 据我所知,std::unique_ptr 在这里没有任何好处。只需首先使用原始指针即可。
  • 你读过任何文档吗?我想你想要std::unique_ptr::release
  • @Blastfurnace 是的......我确实没有仔细阅读描述文档。也许我虽然 Release 就像 IUnknown::Release() 所以我没有进一步检查 unique_ptr::release 它是什么。谢谢!
  • 我认为该网站上的文档通常清晰直接,这是一个很好的资源,您可能希望将其添加为书签。

标签: c++ pointers smart-pointers


【解决方案1】:

如何将 unique_ptr 移动到原始指针?

嗯,这是避免在此处使用 unique_ptr 的任何好处的一种方法。

可以使用std::unique_ptr::release(),但首先使用unique_ptr 毫无意义。考虑改为返回unique_ptr。这样调用者就知道他们拥有指针,并且当他们停止使用它时,数组将被释放。否则,您必须记录调用者必须解除分配以及他们必须如何执行。

如果这不是一个选项,那么unique_ptr 根本就没有用处,除非您正在做一些可能会在构造数组和返回它之间发生的事情,并且为了简单起见将其省略。

【讨论】:

  • unique_ptr 与发布结合使用并非毫无意义。您可能正在处理需要原始指针的外部代码。然后您可以在构建这些对象期间使用unique_ptr。如果在您将它们交给外部代码之前引发任何异常,则该对象仍将被删除。
  • @Aedoro 正如我所说,“unique_ptr 根本没有用处除非你正在做一些可能会在构造数组和返回它之间发生的事情
【解决方案2】:

由于 ppRetBuf 和 buf 是两种不同的数据类型 编译器会给出错误信息。

为了做你想做的事,你需要 在 buf 上调用释放

*ppRetBuf = buf.release();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2021-03-18
    • 2015-05-02
    • 1970-01-01
    相关资源
    最近更新 更多