"A()" vs. "A() = default;" vs. 隐式 A()?

"A()" vs. "A() = default;" vs. Implicit A()?

本文关键字:vs 隐式 default      更新时间:2023-10-16
#include <vector>
// version 1
struct A
{
    std::vector<int> m_coll;
    // The compiler will generate a ctor A() here
};
// version 2
struct A
{
    std::vector<int> m_coll;
    A(){}
};
// version 3
struct A
{
    std::vector<int> m_coll;
    A() : m_coll(){}
};
// version 4
struct A
{
    std::vector<int> m_coll;
    A() = default;
};

四个版本有什么区别?

m_coll是否保证在所有这些版本中默认初始化?

每当添加额外的基准面时,都更容易考虑各种选项。 考虑:

struct A {
  int i;
  std::vector<int> coll;
};

在这种情况下,编译器会为您生成默认的 c'tor,但i未初始化,因此您必须显式设置它。

让我们改进一下:

struct B {
  int i {};
  std::vector<int> coll;
};

对于B,编译器也会为你生成一个默认的 c'tor,但i是在类中初始化的,因此一个默认构造的 B 类型的对象是完全初始化的。 现在假设我想添加一个用户定义的 c'tor:

struct C {
  int i {};
  std::vector<int> coll;
  C(int const j) : i{j} {}
};

添加用户定义的 c'tor 会禁止自动生成默认构造函数。 因此,要启用默认的c'tor,可以做一些不同的事情:

struct D1 {
  int i {};
  std::vector<int> coll;
  D1(int const j) : i{j} {}
  D1(){}
};

虽然以上内容格式良好,但我觉得它很丑。 这里D1(){}默认的 c'tor,i 被适当初始化,因为它有一个类内初始值设定项。 但是,执行以下操作更具描述性:

struct D2 {
  int i {};
  std::vector<int> coll;
  D2(int const j) : i{j} {}
  D2() = default;
};

这样,您可以读到您正在启用默认的 c'tor。

根据我的经验,每当需要为复制/移动构造函数和赋值运算符启用默认定义以及为虚拟析构函数启用默认定义时,使用 default 会更有帮助。

长话短说:每当需要启用编译器将禁止的 c'tor 或赋值运算符时,或者需要虚拟析构函数的默认定义时,请使用 default