1

重複の可能性:
この場合、コピー コンストラクターが呼び出されないのはなぜですか?

次のコード スニペットを検討してください。

#include <iostream>

using namespace std;

class Test
{
        char name[16];
        public:
        Test ()
        {
                cout <<"Inside Constructor"<<endl;
        }

        Test (const Test & t)
        {
                cout <<"Inside Copy Constructor "<<endl;
        }

};

Test f()
{
        return Test();
}

int main ( int argc, char ** argv)
{
        Test t;
        Test t1 = f();

}

Test t1= f() -> f() を呼び出し、Test オブジェクトを返します。私の理解では、コピー コンストラクターを呼び出す必要があります。しかし、次の出力が得られます。

Inside Constructor
Inside Constructor

私の理解の何が問題になっていますか?

4

4 に答える 4

2

ここで2 つのコピー省略が発生します。

1 つ目は、一種の戻り値の最適化です (式の結果を のTest()戻り値である一時オブジェクトにコピーする代わりに、式は、の戻り値でfあるTest()一時オブジェクトに直接構築することによって評価されますf)。

2 つ目は、 の初期化式t1からそれ自体へのコピーの省略です (したがって、 の戻り値である一時をt1にコピーする代わりに、 の戻り値である一時が に直接構築されます)。ft1ft1

2 つのエリシオンは連鎖します。つまりt1、 の戻り値を構築するときに のメモリが宛先として使用され、 の戻り値fのメモリが をf構築するときに宛先として使用されTest()ます。したがって、事実上t1、引数なしのコンストラクターによって直接初期化され、コピーは必要ありません。

コピー コンストラクターの省略は、C++03 の 12.8/15 および C++11 の 12.8/31 の標準で定義されています (移動の省略も可能です)。プログラムの観察可能な動作を変更するため、特定の許可が必要です(あなたの場合、コピーコンストラクターの副作用である出力が省略されます)。そのため、規格で定義された条件下でのみ実行できます。

これらの省略は両方とも、ソースが一時的な場合に、C++03 で許可されている2 番目(C++11 では 3 番目) の省略の例です。

最初に許可された省略は、「名前付き戻り値の最適化」と呼ばれることが多く、ソースが一時的でない場合に特定の種類のコピーを省略できるようにします。

于 2012-10-18T08:44:37.753 に答える
1

戻り値の最適化により、必要な余分なコピーが削除されるためです。

于 2012-10-18T08:29:23.200 に答える
1

これは戻り値の最適化と呼ばれます。

于 2012-10-18T08:29:33.233 に答える
0

コピー コンストラクターを呼び出すことはないと思います。デフォルトのコンストラクターを呼び出し、一時コピーを取得してから、代入演算子が呼び出されます。

編集。OK 読み間違えましTest t1 = f();た。RVO は実際に動き出している可能性が最も高いでしょうf()。したがって、本質的には に等しいTest t1 = Test();です。

これは、プログラムの動作の変更につながる可能性がある場合でも、適用が許可されているいくつかの最適化の 1 つだと思います。最適化フラグを操作すると、コピー コンストラクター (+古いオブジェクトのデストラクタ) を実行できる可能性があります。

于 2012-10-18T08:34:42.137 に答える