0

次のコードに疑問があります。機能fun1fun2はどちらも同じです。1 つはローカル変数を宣言し、もう 1 つは引数によって変数を渡します。次に、fun1 の場合、コピー コンストラクターが呼び出されないのはなぜですか。

#include<stdio.h>
#include<iostream>
using namespace std;
class A
{
    public:
A()
{
    printf("constructor\n");
}
A(const A&)
{
    printf("copy cons\n");
}
~A()
{
    printf("destructor\n");
}
};
A fun1()
{
A obj;
return obj;
}
A fun2(A obj)
{
return obj;
}

int main()
{
    A a=fun1();
    printf("after fun1\n");
    A b;
    A c = fun2(b);
}

出力

constructor
after fun1
constructor
copy cons
copy cons
destructor
destructor
destructor
destructor
4

2 に答える 2

1

では、なぜ fun1 の場合にコピー コンストラクターが呼び出されないのでしょうか。

アクセス可能なコピーまたは移動コンストラクターがある場合A、コンパイラーはコピーを除外することを選択できます。これは、いわゆる (名前付きの) 戻り値の最適化((N)RVO)です。

于 2013-01-07T08:02:24.103 に答える
1

Named Return Value Optimizationが原因で、コンパイラがコードに対して実行する最適化です。関数 fun1() の戻り値の型が (型 A の) fun1() 内の一時オブジェクトと同じであるという事実を認識しているため、そのコピーを作成しません (コピー コンストラクターを呼び出しません)。リターンステートメント。

最適化せずにコードをコンパイルしてみて、コピー コンストラクターが呼び出されるかどうかを確認できます。gcc コンパイラを使用している場合、最適化をオフにするコンパイラ フラグは「-O0」です。

于 2013-01-07T08:02:41.777 に答える