取消引用临时unique_ptr

Kam*_*Kam 15 c++ unique-ptr c++11

unique_ptr<A> myFun()
{
    unique_ptr<A> pa(new A());
    return pa;
}

const A& rA = *myFun();
Run Code Online (Sandbox Code Playgroud)

此代码编译但rA包含垃圾.有人可以向我解释为什么这段代码无效?

注意:如果我在解除引用之前将返回指定给myFun命名unique_ptr变量,它可以正常工作.

mas*_*oud 12

该unique_ptr会通过所有权转让给其他unique_ptr的,但在你的代码没有什么可以捕获从返回指针的所有权.换句话说,它不能转让所有权,因此它将被破坏.正确的方法是:

unique_ptr<A> rA = myFun(); // Pass the ownership
Run Code Online (Sandbox Code Playgroud)

要么

const A rA = *myFun(); // Store the values before destruction
Run Code Online (Sandbox Code Playgroud)

在您的代码中,返回的指针将被解析,引用将引用一个即将破坏的对象,之后使用此引用调用未定义的行为.


kfs*_*one 6

unique_ptr<A> myFun()
{
    unique_ptr<A> pa(new A());
    return pa;
}

const A& rA = *myFun();
Run Code Online (Sandbox Code Playgroud)

你在最后一行做了什么:

unique_ptr<A>* temporary = new unique_ptr<A>(nullptr);
myFun(&temporary);
const A& rA = *temporary.get();
delete temporary; // and free *temporary
Run Code Online (Sandbox Code Playgroud)

删除时,temporary它与您签订合同,它拥有指针和引用的内存.所以它破坏A并释放了记忆.

与此同时,你偷偷地将指向该内存的指针作为对该地址对象的引用.

您可以将指针传输到本地unique_ptr:

unique_ptr<A> a = myFun();
Run Code Online (Sandbox Code Playgroud)

或者您可以复制对象:

A = *myFun().get();
Run Code Online (Sandbox Code Playgroud)

myFun()临时的'A' 仅在声明结束时被破坏,因此它存在于副本中.