Выделение временного unique_ptr
unique_ptr<A> myFun()
{
unique_ptr<A> pa(new A());
return pa;
}
const A& rA = *myFun();
Этот код компилируется, но rA
содержит мусор. Может кто-нибудь объяснить мне, почему этот код недействителен?
Примечание: если я назначу возврат myFun
к именованной переменной unique_ptr
перед разыменованием ее, она отлично работает.
Ответы
Ответ 1
unique_ptr
передаст право собственности другому unique_ptr
, но в вашем коде нет ничего, чтобы захватить собственность с возвращаемого указателя. Другими словами, он не может передать право собственности, поэтому он будет разрушен.
Правильный способ:
unique_ptr<A> rA = myFun(); // Pass the ownership
или
const A rA = *myFun(); // Store the values before destruction
В вашем коде возвращаемый указатель будет скомпенсирован, и ссылка ссылается на объект, который быстро разрушается, после чего с использованием этой ссылки вызывается поведение undefined.
Ответ 2
unique_ptr<A> myFun()
{
unique_ptr<A> pa(new A());
return pa;
}
const A& rA = *myFun();
Что вы сделали в этой последней строке:
unique_ptr<A>* temporary = new unique_ptr<A>(nullptr);
myFun(&temporary);
const A& rA = *temporary.get();
delete temporary; // and free *temporary
Когда вы удаляете temporary
, у вас есть контракт с вами, что он владеет указателем и памятью, на которую ссылается. Таким образом, он разрушает A
и освобождает память.
Между тем, вы скрытно указали на эту память как ссылку на объект по этому адресу.
Вы можете либо перенести указатель на локальный уникальный_ptr:
unique_ptr<A> a = myFun();
или вы можете скопировать объекты:
A = *myFun().get();
"A", к которому myFun()
временный разрушается только в конце инструкции, поэтому он присутствует для копии.