2

[abc e = a + b]が呼び出された場合、コピーコンストラクターは呼び出されません。

class abc{
        int i;
        public:
        abc()
            {
            i = 10;
            cout<<"constructor"<<endl; 
        }
        abc(const abc &a)
        {   
            cout<<"copy constructor"<<endl;
            i = a.i; 
        }
        abc operator=(const abc &a)
        {
            cout<<"operator="<<endl;
            abc temp;
            temp.i = a.i;
            return temp;
        }
        abc operator+(abc& a)
        {   
            cout <<"Operator+ called"<<endl;
            abc temp;
            temp.i = i+a.i;
            return temp ;
        }
    };

    int main()
    {
        abc a,b;
        cout <<"----------------------------------------------"<<endl;
        a = b;
        cout <<"----------------------------------------------"<<endl;
        abc c = a;
        cout <<"-----------------------------------------------"<<endl;
        abc d(a);
        cout <<"-------------------------------------------"<<endl;
        **abc e = a+b;** 
    }

ただし、オーバーロード演算子メソッドが、クラスabcのオブジェクトへの参照を返す次のメソッドに置き換えられた場合、コピーコンストラクターが呼び出されます。

abc& operator=(const abc &a)
    {
        cout<<"operator="<<endl;
        i = a.i;
        return *this;
    }
    abc& operator+(const abc& a)
    {   
        cout <<"Operator+ called"<<endl;
        i = i+a.i;
        return *this ;
    }

なぜこれが起こるのか説明してもらえますか?

4

3 に答える 3

1

これは、戻り値の最適化が原因で発生しています。

コンストラクターが参照を返す場合、コストのかかるメモリコピー操作は行われないため、この場合は最適化が行われないため、期待どおりに機能します。値を返す場合、最適化が開始され、(あなたにとって)やや予想外の方法で機能しますが、標準では許可されています。

于 2012-08-13T05:35:45.747 に答える
0

その最適化は、標準によって明示的に許可されています。

n3376
12.8段落31:

特定の基準が満たされると、コピー/移動操作用に選択されたコンストラクターやオブジェクトのデストラクタに副作用がある場合でも、実装はクラスオブジェクトのコピー/移動構造を省略できます。

この最適化は、RVO(この場合)および特定の条件下でNRVOを介して実現できます。

于 2012-08-13T05:32:34.617 に答える
0

コンパイラで最適化オプションを無効にすることができます。コードのコンパイル中に使用される最適化フラグを確認してください。

于 2012-08-23T14:16:37.097 に答える