0

以下のようなプログラムを書きました。

#include <iostream>

using namespace std;

class A {
public:
    A() {
    }
    A(A &a) {
        id = a.id;
        cout << "copy constructor" << endl;
    }
    A& operator=(A &other) {
        id = other.id;
        cout << "copy assignment" << endl;
        return *this;
    }
    A(A &&other) {
        id = other.id;
        cout << "move constructor" << endl;
    }
    A& operator=(A &&other) {
        id = other.id;
        cout << "move assignment" << endl;
        return *this;
    }
public:
    int id = 10;
};

A foo() {
    A a;
    return a;
}

int main()
{
    A a;
    A a2(a); // output: copy constructor
    A a3 = a2; // output: copy constructor
    a3 = a2; // output: copy assignment
    A a4 = foo(); // output: 
    a4 = foo(); // output: move assignment
    return 0;
}

Mac OSでコンパイルしました。出力は次のとおりです。

copy constructor
copy constructor
copy assignment
move assignment

私の質問は次のとおりです。

  1. の出力A a4 = foo();が空なのはなぜですか? 移動コンストラクターを呼び出す必要があると思いました。
  2. の出力A a3 = a2;がのcopy constructor代わりにあるのはなぜcopy assignmentですか?
4

2 に答える 2

5
  1. 必要に応じて、コピーと移動がコンパイラによって省略される可能性があるためです。関連するコンストラクターは引き続き存在する必要がありますが、それらが呼び出されない可能性があることが標準で明示的に述べられています。(これは、標準定義の最適化のまれな例であり、特に戻り値の最適化も標準定義にすることができます。)

  2. 初期化で を使用すると=、代入ではなく構築が実行されるためです。これが構文であることはやや混乱します。A a3(a2)、[本質的に]同等であり、この点でより明確になります。

于 2013-10-27T01:19:11.953 に答える