2016-01-04 43 views
4

我想要做这样的事情:如果我返回unique_ptr,原始对象会被删除吗?

unique_ptr<MyObj> MyFunc() { 
    MyObj* ptr = new MyObj(); 
    ... 
    return unique_ptr<MyObj>(ptr); 
} 

unique_ptr<MyObj> value = MyFunc(); 

但我不确定如果当临时值的函数返回后销毁的对象将被删除。如果是这样,我应该如何正确实现一个返回unique_ptr的函数?

回答

1

分配指针的方式是std::make_unique。对于其他类型的智能指针也有类似的功能,例如, std::make_shared

如果你想从函数返回它,你应该使用std :: move,因为unique_ptrs不喜欢被复制。

返回这样的:return std::move(ptr);

+0

当我返回std :: move(ptr)时,应该返回的类型是“unique_ptr ”还是'&& unique_ptr '而不是?我以前从未见过后者,但似乎在移动语义中我们需要双引用? – OneZero

+0

分配一个唯一的ptr的最好方法可能是'std :: make_unique',但这与问题无关。 –

+0

当你返回一个unique_ptr时,你不需要使用std :: move。上面的代码按照设计工作。 –

10

没有,对象也不会在功能范围结束删除。这是因为unique_ptr的移动构造函数会将所有权语义“移动”到新的unique_ptr对象,并且销毁旧的unique_ptr不会导致删除分配的对象。

注意:这不是这样做的正确方法。如果在内存分配点和​​创建点之间引发异常,则会发生内存泄漏。

+1

关于异常安全性的说明很好 –

+0

尽管通过从唯一指针移动来管理原始指针最终将被删除,所以该函数不会创建内存泄漏。同意这个说明,upvoted! – vsoftco

3

虽然代码可以编译和工作,它是最好的std::make_unique直接的工作:

return std::make_unique<T>(/* your arguments*/); 

您的片段可以创造一些问题,如:

  1. new可如果抛出std::bad_alloc没有可用内存
  2. MyObj可以抛出异常
  3. ptr可能会迷路,直到它被分配到unique_ptr
+0

前两个通常不是问题。 – SergeyA

+0

“通常”为谁? –

+0

对于功能与Func()类似的功能的作者。 – SergeyA

0

如果没有问题,您的代码应该工作;原始对象将在MyFunc函数中创建,并且其所有权将被传回给调用者。但是,创建std::unique_ptr的最佳方法是使用std::create_unique(以避免干预错误条件时可能发生的泄漏)。您可以使用调试器或某个控制台输出来验证这是否正确发生;我的扩展代码(如下所示)的/修改产生以下输出,验证只有一个对象被创建,它是在的main结束时)破坏:

Created 
999 
Destroyed 

下面的代码:

#include <iostream> 
#include <memory> 

class MyObj 
{ 
public: 
    MyObj(int v) 
    : value(v) 
    { 
    std::cout << "Created" << std::endl; 
    } 

    ~MyObj() 
    { 
    std::cout << "Destroyed" << std::endl; 
    } 

    int value; 
}; 

std::unique_ptr<MyObj> MyFunc() 
{ 
    auto ptr = std::make_unique<MyObj>(999); 

    // ...do other stuff here?... 

    // return std::move(ptr); // Loki Astari says move() is unnecessary 
    return ptr; 
} 

int main() 
{ 
    auto p = MyFunc(); 
    std::cout << p->value << std::endl; 
    return 0; 
} 
+0

@LokiAstari谢谢!删除。 (这对我来说已经有一段时间了,我已经在Python地区待了一年了!) – aldo

相关问题