1

这是关于对象销毁与返回值优化的 C++ 规范的问题。

我可以期望 RVO 在std::unique_ptr<>清理之前返回正确的值吗?

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

2 回答 2

5

无论有没有 RVO,它都会返回正确的值(在这种情况下没有 RVO)。该函数返回一个具体的Foo,因此*ptr将在指针销毁之前复制到返回值中。

这意味着,

Foo foo;
foo = Bar();

类似于(将 unique_ptr 展开更明确)

  Foo foo;
  Foo* ptr = new Foo;
  foo = *ptr;
finally:
  delete ptr;
于 2012-12-08T07:05:28.057 回答
1

当函数返回类类型对象时,仅在两种情况下允许使用 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
}
于 2012-12-08T07:21:31.750 回答