Это вопрос о спецификациях C ++ по уничтожению объектов против Return-Value-Optimization.
Могу ли я ожидать, что RVO вернет правильное значение до того, как std :: unique_ptr<> очистка?
Foo
Bar()
{
std::unique_ptr<Foo> ptr = new Foo;
return *ptr;
}
Он вернет правильное значение с или без RVO (и в этом случае RVO не существует). Функция возвращает бетон Foo
, так *ptr
будет скопированный в возвращаемое значение до уничтожения указателя.
Это означает,
Foo foo;
foo = Bar();
похоже на (развернуть unique_ptr, чтобы быть более явным)
Foo foo;
Foo* ptr = new Foo;
foo = *ptr;
finally:
delete ptr;
Когда функция возвращает объект типа класса, RVO допускается только при двух обстоятельствах:
Таким образом, ваш код не будет вызывать RVO.
Если Foo
Объект объявляется с автоматическим хранением, компилятору разрешено делать RVO:
Foo bar()
{
Foo foo;
return foo; // foo can be constructed directly as the returned object
}
Если по какой-то причине вы должны создать объект с new
и хотите исключить операцию копирования, вы можете использовать std::move
, который изменит выражение в значение:
Foo bar()
{
std::unique_ptr<Foo> ptr(new Foo);
return std::move(*ptr); // No deep copy if Foo implements
// its own move constructor
}