简体   繁体   中英

Will the original object get deleted if I return a unique_ptr?

I want to do something like this:

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

unique_ptr<MyObj> value = MyFunc();

But I'm unsure if the object will be deleted when the temporary value was destructed after the function returns. If so, how should I implement correctly a function that returns a unique_ptr ?

No, the object will not be deleted when function scope ends. This is because move constructor of unique_ptr will 'move' the ownership semantics to the new unique_ptr object, and destruction of the old unique_ptr will not cause deletion of the allocated object.

Note : This is not the right way of doing this. If there is an exception thrown between the point of memory allocation and unique_ptr<> creation you will have a memory leak.

Although the code can compile and work, it is the best to work with std::make_unique directly:

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

your snippet can create some problems such as:

  1. new can throw std::bad_alloc if no memory available
  2. MyObj can throw an exception
  3. ptr can get lost in the way until it is assigned to the unique_ptr

The way to allocate the pointer is std::make_unique . There are similar functions for the other types of smart pointers as well, eg std::make_shared .

If you want to return it from a function, you should use std::move, since unique_ptrs don't like to be copied.

Return it like this: return std::move(ptr);

If nothing goes wrong, your code should work; the original object will be created within the MyFunc function and its ownership will be transferred back to the caller. However, the best way to create a std::unique_ptr is with std::create_unique (to avoid possible leaks upon intervening error conditions). You can verify that this happens correctly with either a debugger or some console output; My expansion/modification of your code (shown below) produces the following output, verifying that only one object is created and it is destroyed at the end of main ):

Created
999
Destroyed

Here's the code:

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM