c++ - 在构造函数或运算符重载器的末尾键入 `= default` 的目的是什么(例如 : copy assignment operator) declaration in a class?

标签 c++ constructor default default-constructor

<分区>

这个对 What is The Rule of Three? 的回答有以下代码。请注意,除第一个构造函数外,所有构造函数的末尾都有 = default;:

class person
{
    std::string name;
    int age;

public:
    person(const std::string& name, int age);        // Ctor
    person(const person &) = default;                // 1/5: Copy Ctor
    person(person &&) noexcept = default;            // 4/5: Move Ctor
    person& operator=(const person &) = default;     // 2/5: Copy Assignment
    person& operator=(person &&) noexcept = default; // 5/5: Move Assignment
    ~person() noexcept = default;                    // 3/5: Dtor
};

虽然我以前见过很多次,但我不明白什么时候可以使用 = default,或者为什么。在我看来,如果您想要 C++ 提供的 default 构造函数或赋值运算符,您可以只删除该声明(以及任何关联的定义),不是吗?

目的是明确禁止给定类型的任何其他构造函数吗?例如:也许这个

person& operator=(const person &) = default;     // 2/5: Copy Assignment

位于类定义的顶部只会让类的任何读者或用户清楚地知道不存在或不可能存在其他手动/显式复制赋值运算符?

我在这里需要一些帮助来理解:

  1. 机制/它的作用是什么(即:在类中的构造函数或函数定义之后使用 = default)?
    1. 它也适用于第一个构造函数吗?我在示例中没有看到它:person(const std::string& name, int age);(另外:这个构造函数有名字吗?也许是“通用构造函数”?
  2. 何时使用
  3. 为什么要用它

我对 C++ 的更高级功能还很陌生。

更新

以下是来自 Scott Meyers: "A Concern about the Rule of Zero" 的一些额外见解(重点添加):
(如果这个问题没有结束,我可能会将其作为答案)。

The addition of the destructor has the side effect of disabling generation of the move functions, but because Widget is copyable, all the code that used to generate moves will now generate copies. In other words, adding a destructor to the class has caused presumably-efficient moves to be silently replaced with presumably-less-efficient copies. That strikes me as the kind of thing that (1) is likely to surprise people and (2) could really complicate debugging.

I'm inclined to recommend that a better way to rely on the compiler-generated copy and move functions is to expressly say that they do the right thing--to define them via =default:

 class Widget {
 public:
   Widget(const Widget&) = default;
   Widget(Widget&&) = default;

   Widget& operator=(const Widget&) = default;
   Widget& operator=(Widget&&) = default;

   ...
 };

With this approach, the spirit of the Rule of Zero remains: classes that don't manage resources should be designed so that the compiler-generated functions for copying, moving, and destruction do the right things. But instead of expressing this by not declaring those functions, it's expressed by declaring them explicitly and equally explicitly opting in to the compiler-generated implementations.

What do you think? Does this advice make sense? Should the Rule of Zero perhaps be the Rule of the Five defaults?

Scott 的博文到此结束。然后,在他的帖子下方的评论中,他说:

I think "The Rule of All or Nothing" would be a pretty good rule.


对被标记为重复/请求重新打开此问题的响应:

我觉得问题标记为 "already has an answer" here没有涵盖我所问问题的细微差别,我的问题应该重新开放,以允许其他人就我的问题的具体细节提供更多答案和见解。我看过它的答案。它的问题集中在显式 default 通用构造函数上,但我的问题集中在显式 default 一个或多个“Rule of 5”构造函数/赋值运算符,以及如何这会影响其他人的互动和 react 。我现在投票重新提出我的问题。

沙盒:https://godbolt.org/z/vWMsd3

另见

  1. http://scottmeyers.blogspot.com/2014/03/a-concern-about-rule-of-zero.html
  2. What is The Rule of Three?
  3. The new syntax "= default" in C++11
  4. How is "=default" different from "{}" for default constructor and destructor?

最佳答案

看看 Howard Hinnant 的这张表,它显示了何时隐式默认或未声明特殊方法:

enter image description here

是啊.. 如您所见,规则非常复杂,如果您有一些用户声明的特殊成员,则试图弄清楚自己是隐式默认的特殊成员还是未声明的根本不是一个选项。

所以经验法则是,如果您至少声明了其中一个,那么您应该默认所有其余的。

关于c++ - 在构造函数或运算符重载器的末尾键入 `= default` 的目的是什么(例如 : copy assignment operator) declaration in a class?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63855090/

相关文章:

C++ 函数返回指针不会造成段错误

c++ - 构造函数中对默认构造函数的 undefined reference

c++ - 模板默认参数作为指向自身的指针

c++ - 我可以在流式传输/写入时同时读取 mp4 文件的较早部分吗?

c++ - 在我的网站上运行python,C,C++应用程序

c++ - 什么时候分配和初始化变量?

c++ - 链式调用构造函数中 shared_from_this 的问题

android - 默认 Android Gallery 应用程序不编译 :(

.net - 在 Visual Studio 2010 上将默认值 "Default.aspx"更改为 "Index.aspx"

c++ - 为什么 C++ 中空类的大小不为零?