我想做这样的事情:
unique_ptr<MyObj> MyFunc() {
MyObj* ptr = new MyObj();
...
return unique_ptr<MyObj>(ptr);
}
unique_ptr<MyObj> value = MyFunc();
但是我不确定在函数返回后临时值被破坏时是否会删除该对象。如果是这样,我应该如何正确实现一个返回unique_ptr
?
答案 0 :(得分:11)
不,当功能范围结束时,不会删除该对象。这是因为unique_ptr
的移动构造函数会将所有权语义“移动”到新的unique_ptr
对象,而旧的unique_ptr
的销毁将不会导致删除已分配的对象。
注意:这不是正确的做法。如果在内存分配点和unique_ptr<>
创建点之间抛出异常,则会发生内存泄漏。
答案 1 :(得分:3)
虽然代码可以编译和工作,但最好直接使用std::make_unique
:
return std::make_unique<T>(/* your arguments*/);
您的代码段可能会产生一些问题,例如:
new
可以抛出std::bad_alloc
MyObj
可以抛出异常ptr
可能会在分配到unique_ptr
答案 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;
}