RVO vs std :: unique_ptr & lt; & gt; уборка

Это вопрос о спецификациях C ++ по уничтожению объектов против Return-Value-Optimization.

Могу ли я ожидать, что RVO вернет правильное значение до того, как std :: unique_ptr<> очистка?

Foo
Bar()
{
std::unique_ptr<Foo> ptr = new Foo;
return *ptr;
}

1

Решение

Он вернет правильное значение с или без RVO (и в этом случае RVO не существует). Функция возвращает бетон Foo, так *ptr будет скопированный в возвращаемое значение до уничтожения указателя.

Это означает,

Foo foo;
foo = Bar();

похоже на (развернуть unique_ptr, чтобы быть более явным)

  Foo foo;
Foo* ptr = new Foo;
foo = *ptr;
finally:
delete ptr;
5

Другие решения

Когда функция возвращает объект типа класса, 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
}
1

По вопросам рекламы [email protected]