它们之间是否等效:隐式构造函数、无参空函数体构造函数和显式默认构造函数?

4
struct A1
{
    int n;        
};

struct A2
{
    int n;
    A2(){}        
};

struct A3
{
    int n;
    A3() = default;        
};

问题1:

C++标准是否保证类A1A2A3是完全等同的?

问题2:

A1 a1;
A2 a2;
A3 a3;

编译器不会按照C++标准对a1.na2.na3.n进行零初始化吗?

2
不确定你的意思是什么...它们不相等,因为第一个是一个聚合体而第二个不是。 - Marco A.
2个回答

2

有一个区别,A1A3聚合类型,而A2不是,因为它具有用户定义的构造函数。

类类型(通常为结构体或联合体),具有

  • ...
  • 没有用户提供的、继承的或显式的(自C++17起)构造函数(显式默认或已删除的构造函数是允许的)(自C++11起)
  • ...

这意味着对于A1A3,它们可以进行聚合初始化,而A2则不能。

A1 a1{99}; // fine;  n is initialized to 99
A3 a3{99}; // fine;  n is initialized to 99
A2 a2{99}; // error; no matching constructor taking int found

编译器会不会根据 C++ 标准对 a1.na2.na3.n 进行零初始化呢?
根据 默认初始化 的规则,如果它们是自动存储期的,这里没有进行零初始化,所有值都是不确定的。另一方面,静态和线程本地对象会被 零初始化

2
它们不相等,因为它们是不同的实体并且有不同的初始化:第一个和最后一个是聚合体,而第二个不是。
聚合体是指没有用户提供构造函数(12.1)、非静态数据成员没有花括号或等号初始化器(9.2)、没有私有或保护的非静态数据成员(第11条),没有基类(第10条)和没有虚函数(10.3)的数组或类(第9条)。
请在此处阅读更多信息:什么是聚合体和POD,以及它们为什么很特殊? 因此,聚合初始化适用于 A1 和 A3,但不适用于 A2。
struct A1
{
    int n;        
};

struct A2
{
    int n;
    A2(){}        
};

struct A3
{
    int n;
    A3() = default;        
};


int main()
{
   A1 obj1{42};
   //A2 obj2{42}; // error
   A3 obj3{42};


   return 0;
}

变量将会被默认初始化。这段代码中的a1,a2和a3都是自定义类型的对象,它们的成员变量n没有被显式地初始化。根据C++标准,默认初始化会对基本类型进行零初始化,而对于用户自定义类型,默认初始化不会对非静态数据成员进行任何操作。因此,在这个例子中,a1.n,a2.n和a3.n都将保持未定义的状态。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接