如果我返回unique_ptr,原始对象是否会被删除?

时间:2016-01-04 18:28:00

标签: c++ unique-ptr

我想做这样的事情:

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

unique_ptr<MyObj> value = MyFunc();

但是我不确定在函数返回后临时值被破坏时是否会删除该对象。如果是这样,我应该如何正确实现一个返回unique_ptr

的函数

4 个答案:

答案 0 :(得分:11)

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

注意:这不是正确的做法。如果在内存分配点和unique_ptr<>创建点之间抛出异常,则会发生内存泄漏。

答案 1 :(得分:3)

虽然代码可以编译和工作,但最好直接使用std::make_unique

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

您的代码段可能会产生一些问题,例如:

    如果没有可用内存,
  1. new可以抛出std::bad_alloc
  2. MyObj可以抛出异常
  3. ptr可能会在分配到unique_ptr
  4. 之前迷路

答案 2 :(得分:1)

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

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

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

答案 3 :(得分: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;
}