使用“= default”声明复制构造函数与根本不声明它有什么区别?

What is the difference between declaring a copy constructor with "= default" or not declaring it at all?

我正在尝试了解为各种函数自动生成的编译器代码的行为,例如:

  1. 析构函数
  2. 拷贝构造函数
  3. 赋值运算符
  4. 移动构造函数
  5. 移动赋值运算符

与未声明的情况相比,使用“= default”声明它们会导致任何功能差异吗? 上面列出的函数对这个问题的回答是否不同? 如果没有功能差异,使用这两种情况的后果是什么?

复制使用“= default”声明的构造函数

class MyClass
{
public:
    MyClass();
    MyClass(MyClass &other) = default;
    
    OtherClass some_member;
};

未声明复制构造函数:

class MyClass
{
public:
    MyClass();

    OtherClass some_member;
};

在某些情况下,复制构造函数被默认删除。最简单的例子:

class myClass {

public:
    myClass();
    myClass(myClass &&);
};

myClass a;

void func()
{
    myClass b=a;  // ERROR
}

我不解释编译错误的原因,而是逐字粘贴来自我的编译器的编译错误:

‘constexpr myClass::myClass(const myClass&)’ is implicitly declared as deleted because ‘myClass’ declares a move constructor or move assignment operator

显式声明默认值或 user-defined 复制构造函数将使代码编译。

还有其他几个原因。显式声明的复制构造函数删除隐式声明的移动构造函数,其中一个。