web-dev-qa-db-ja.com

C ++:一時的な引数の寿命?

MyClassの新しいインスタンスを次のように関数の引数として作成する場合:

_class MyClass
{
  MyClass(int a);
};    

myFunction(MyClass(42));
_

規格は、デストラクタのタイミングを保証していますか?

具体的には、myFunction()の呼び出し後の次のステートメントの前に呼び出されると想定できますか?

67
shoosh

一時オブジェクトは、それらが含まれる完全な式の終わりに破棄されます。

完全式とは、他の式の部分式ではない式です。通常、これは、ステートメントの終わりを示す_;_(またはifwhileswitchなどの場合は_)_)で終了することを意味します。あなたの例では、それは関数呼び出しの終わりです。

const参照にバインドすることにより、一時オブジェクトの寿命を延ばすことができることに注意してください。そうすることで、それらの寿命を参照の寿命まで延長します。

_MyClass getMyClass();

{
  const MyClass& r = getMyClass(); // full expression ends here
  ...
} // object returned by getMyClass() is destroyed here
_

返されるオブジェクトを変更する予定がない場合は、戻り値の最適化が適用されていなかった場合に備えて、コピーコンストラクターの呼び出しを保存するのが(MyClass obj = getMyClass();と比較して)良い方法です。残念ながらあまり知られていません。 (ただし、C++ 11の移動のセマンティクスは、その有用性を低下させると思います。)

103
sbi

誰もがあなたの質問に答える12.2/3または同様のものを正しく引用しています:

一時オブジェクトは、作成されたポイントを(字句的に)含む完全式を評価する最後のステップとして破棄されます。

私はそれを面白いと思います次のページに私の標準の印刷では、12.2/4はこう言います:

一時式が完全な式の終わりとは異なる時点で破棄される2つのコンテキストがあります。

どちらもあなたの例には当てはまりません。どちらも初期化子での一時の使用に関連しています。しかし、C++標準のようなトリッキーなビーストに対処するときは、自分のことを頭に入れておかなければならないことを示しています。

23
Steve Jessop

標準は確かに保証を提供しています-セクション12.2/5から:

関数呼び出し(5.2.2)の参照パラメーターに一時的にバインドされたものは、呼び出しを含む完全な式が完了するまで存続します。

ただし、コードでは、パラメーターが参照によって渡されているのか、値によって渡されているのかが明確ではありません。

10
anon

セクション12.2、一時オブジェクト、3節、ANSI/ISO C標準では、次のように述べています。

これは シーケンスポイント の概念と密接に関連しています。シーケンスポイントに到達すると、式のすべての副作用が発生することが保証されます。

3
Mike Mueller