“A()”与“A()=默认;”与隐含A()?

时间:2016-07-11 11:11:29

标签: c++ c++11 constructor

#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是否保证在所有这些版本中默认初始化?

1 个答案:

答案 0 :(得分:3)

每当您添加额外数据时,都可以更轻松地考虑各种选项。考虑:

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