RVOによるコピーコンストラクタの最適化

前回の記事でコメント欄にてRVO(Return Value Optimization)というものを教えていただきました。

要はコンパイラが最適化してオブジェクトへの代入なのにコピーコンストラクタを通さずにそのまま代入できるようにしてくれるものです。

使い方は簡単です。クラス名に括弧をつけて代入するだけです。

#include <iostream>
using namespace std;

class CSample {
public:
    CSample () { cout << "CSample()" << endl; }
    CSample (const CSample&) { cout << "CSample(const CSample&)" << endl; }
};

CSample get() {
    // RVOで返す
    return CSample();
}

int main () {
    CSample obj = get();
    return 0;
}
$ main
CSample()

RVOによりコピーコンストラクタが呼ばれていませんね。

もしget関数の戻り値を予め確保したCSampleのオブジェクトを返していた場合はRVOにならずにコピーコンストラクタが呼ばれます。

CSample get() {
    CSample obj;
    // 普通のオブジェクトを返す
    return obj;
}
$ main
CSample()
CSample(const CSample&)

呼ばれちゃってますね。

ただしこのRVOですが、必ず最適化されるかどうかまでは規格的には保証されて無いそうです。最近のコンパイラであれば問題なく最適化されるっぽいので意識する必要はないとは思いますが。