移动语义并复制构造函数

Move semantics and copy constructor

本文关键字:构造函数 复制 语义 移动      更新时间:2023-10-16

我写了一个程序,如下所示:

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

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

编译器正在为以下对象生成默认方法:

A (const A &);
A & operator = (const A &);

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