移动语义和复制构造函数

inj*_*joy 0 c++ copy-constructor move-semantics c++11

我写了一个程序如下:

#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;
}
Run Code Online (Sandbox Code Playgroud)

我在Mac OS上编译了它.输出是:

copy constructor
copy constructor
copy assignment
move assignment
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 为什么输出A a4 = foo();是空的?我认为应该调用move构造函数.
  2. 为什么输出A a3 = a2;copy constructor不是copy assignment

Lig*_*ica 5

  1. 因为如果愿意,编译器可以省略副本和移动.相关构造函数必须仍然存在,但标准中明确声明它们可能不会被调用.(这是标准定义优化的罕见示例,特别是允许返回值优化也是标准定义的.)

  2. 因为=在初始化中的使用执行构造,而不是分配.这是语法,这有点令人困惑.A a3(a2)在这方面,[基本上]是等价的,会更清楚.