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

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

提问人:Yiğit 提问时间:10/25/2020 更新时间:10/25/2020 访问量:195

问:

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

  1. 破坏者
  2. Copy 构造函数
  3. 赋值运算符
  4. Move 构造函数
  5. 移动赋值运算符

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

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

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

未声明复制构造函数:

class MyClass
{
public:
    MyClass();

    OtherClass some_member;
};
C++ 内存 三法则 Rule-of-Zero-Rule-of-Five

评论

1赞 engf-010 10/25/2020
必读,特约会员:howardhinnant.github.io/bloomberg_2016.pdf
0赞 Marek R 10/25/2020
i.imgur.com/rL9uHBGl.png

答:

0赞 Sam Varshavchik 10/25/2020 #1

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

class myClass {

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

myClass a;

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

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

'constexpr myClass::myClass(const myClass&)' 被隐式声明为 已删除,因为“myClass”声明了 move 构造函数或 move 赋值运算符

显式声明默认构造函数或用户定义的复制构造函数将使代码编译。

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

评论

0赞 Yiğit 10/25/2020
谢谢你的回答,SAM,定义上述 5 个函数中的任何一个会导致完全相同的编译错误吗?
0赞 Sam Varshavchik 10/25/2020
其中许多规则因类方法而异。
0赞 Yiğit 10/25/2020
类方法是什么意思?任何成员方法还是 5 种方法之一?我怎样才能学习这些规则?
2赞 Sam Varshavchik 10/25/2020
所有这些或大部分规则都应该在涵盖 C++11 或更高版本的每本高级 C++ 教科书中解释。Stackoverflow.com 并不能真正替代教科书,那么复制/粘贴解释所有这些内容的整个章节就没有多大意义了,不是吗?你在教科书上找到了什么解释,关于这个解释有什么具体的解释是你不清楚的吗?
1赞 Sam Varshavchik 10/25/2020
请参阅 stackoverflow 的 C++ 教科书列表。诚然,教科书不是为了“学习一件特定的事情,而是为了掌握这门学科的好方法”。因为大概这是你的长期目标(对我来说,只学习这个主题后停止学习 C++ 是没有意义的),所以你需要一本教科书。C++是当今使用的最复杂,最难的通用编程语言。没有人会从随机的Youtube视频或在线编码网站学习C++,而只能从教科书中学习。