ページ 11

[C++]クラスオブジェクトを return する際の挙動について

Posted: 2013年11月25日(月) 23:31
by K_Tarou
何度もお世話になっております。
質問の間隔が短くてすみません、なるべく自分一人で解決したいのですが疑問が解けずにトピックを立ててしまいました。
私の環境は Visual Studio C++ 2010 でございます。

質問の内容ですが、以下のようなコードで
► スポイラーを表示
クラスのオブジェクトを作って、そのまま return する関数が2つあります。
ムーブコンストラクタを定義していない普通のクラス(MyClass)のオブジェクトを作り、returnする際には

1. 引数1つのコンストラクタを呼び出す
2. 関数のreturn文のところで一時オブジェクトを作成して、コピーコンストラクタで初期化
3. 呼び出し元へ戻り、定義した代入演算子が呼ばれて、オブジェクトにその内容がコピーされる

という順番に処理が行われると思うのですが、一方で unique_ptrクラスを作る関数では
同じく関数内部でオブジェクトが作られて return する際に、ムーブコンストラクタが呼ばれているようです。


ここで疑問に思ったのですが、関数内部で作られるオブジェクトは、この場合は左辺値であって
右辺値参照を引数にとる、ムーブコンストラクタが呼ばれるのは何故なのだろうということです。

戻り値最適化が行われていて、return文のところで行われる一時オブジェクトの生成(?)が省略されている所為なのかとも考えたのですが、
それならば最適化が行われなかったときはどうなるのか、という疑問もあります。(コピーコンストラクタは unique_ptr クラスでは隠ぺいされているので呼べないと思いますし)

そもそも、オブジェクトが return されるときの挙動を私が勘違いしている所為かもしれませんが、いまいち理解できません。
どうか、よろしくお願いします。

Re: [C++]クラスオブジェクトを return する際の挙動について

Posted: 2013年11月26日(火) 00:14
by h2so5
K_Tarou さんが書きました: 戻り値最適化が行われていて、return文のところで行われる一時オブジェクトの生成(?)が省略されている所為なのかとも考えたのですが、
それならば最適化が行われなかったときはどうなるのか、という疑問もあります。(コピーコンストラクタは unique_ptr クラスでは隠ぺいされているので呼べないと思いますし)
最適化によってコピーコンストラクタが省略されているという考えは合っています。C++11の規格に「コピー省略」というものがあります。
http://ezoeryou.github.io/cpp-book/C++1 ... class.copy
条件次第で、C++の実装はオブジェクトのコピー/ムーブ構築を省略することができる。たとえ、そのオブジェクトのコンストラクターやデストラクターが、副作用を持っていたとしても、遠慮なく省略される。これをコピー省略(copy ellision)という。規格上の用語は「コピー省略」だが、コピーだけではなく、ムーブも省略される可能性がある。
最適化できなかったときはエラーになるだけです。volatileを付けるとエラーになります。

Re: [C++]クラスオブジェクトを return する際の挙動について

Posted: 2013年11月26日(火) 00:47
by K_Tarou
h2so5 さん
迅速なご回答をありがとうございます。
"コピー省略" というものが規格で定義されていることは知りませんでした。エラーになるのですね。
もっとよく調べるべきでした、お騒がせしてすみません。

引用されたページなどを参考にさせて頂き、少しでも多く勉強したいと思います。
ありがとうございました!