RVO vs std :: unique_ptr<>清理

时间:2012-12-08 06:58:37

标签: c++ c++11 return-value-optimization object-destruction

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

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

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

2 个答案:

答案 0 :(得分:5)

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

这意味着,

Foo foo;
foo = Bar();

类似于(展开unique_ptr以使其更明确)

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

答案 1 :(得分: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
}