移动语义和复制构造函数

时间:2013-10-27 01:14:24

标签: c++ c++11 copy-constructor move-semantics

我写了一个程序如下:

#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();的输出为空?我认为应该调用move构造函数。
  2. 为什么A a3 = a2;的输出是copy constructor而不是copy assignment

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:0)

编译器正在为:

生成默认方法
A (const A &);
A & operator = (const A &);

如果您将const限定符添加到copy ctor / assign方法中,您可能会看到预期的结果。