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は次の2つの状況でのみ許可されます。

  • 返される式は、不揮発性の自動オブジェクトの名前、または
  • 返される式は、参照にバインドされていない一時オブジェクトを参照しています。

したがって、コードは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 に答える