它们在隐式 ctor、无参数空体 ctor 和显式默认 ctor 之间是不是等效?

Posted

技术标签:

【中文标题】它们在隐式 ctor、无参数空体 ctor 和显式默认 ctor 之间是不是等效?【英文标题】:Are they equivalent between implicit ctor, no-parameter-empty-body ctor and explicit default ctor?它们在隐式 ctor、无参数空体 ctor 和显式默认 ctor 之间是否等效? 【发布时间】:2017-04-08 10:32:44 【问题描述】:
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 进行零初始化吗?

【问题讨论】:

不知道你的意思是什么......他们不相等,因为例如第一个是聚合,而第二个不是 【参考方案1】:

有一个区别,A1A3 是 aggregate type,而 A2 不是,因为它有一个用户定义的构造函数。

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

... 没有用户提供, inherited, or explicit (since C++17) 构造函数(explicitly defaulted or deleted constructors are allowed) (since C++11) ...

这意味着A1A3 可以聚合初始化,而A2 不能。

A1 a199; // fine;  n is initialized to 99
A3 a399; // fine;  n is initialized to 99
A2 a299; // error; no matching constructor taking int found

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

根据default initialization的规则,如果它们是自动存储时长,这里没有零初始化,所有的值都是不确定的。另一方面,静态和线程本地对象得到zero initialized。

【讨论】:

【参考方案2】:

它们不相等,因为它们是不同的实体并且具有不同的初始化:第一个和最后一个是聚合,第二个不是

聚合是一个数组或一个类(第 9 条),没有用户提供的构造函数 (12.1),非静态数据成员没有大括号或等式初始化器 (9.2),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条),也没有虚函数(10.3)。

在此处了解更多信息:What are Aggregates and PODs and how/why are they special?

所以聚合初始化适用于A1A3,不适用于A2

struct A1

    int n;        
;

struct A2

    int n;
    A2()        
;

struct A3

    int n;
    A3() = default;        
;


int main()

   A1 obj142;
   //A2 obj242; // error
   A3 obj342;


   return 0;

A1 a1; A2 A2; A3 a3;

编译器是否不会按照 C++ 标准对 a1.n、a2.n、a3.n 进行零初始化

变量将是default initialized。

【讨论】:

以上是关于它们在隐式 ctor、无参数空体 ctor 和显式默认 ctor 之间是不是等效?的主要内容,如果未能解决你的问题,请参考以下文章

boost::filesystem::directory_iterator copy-ctor 隐式删除

关于隐式转换和显式转换

隐式转换和显式转换

Oracle sql中的隐式和显式数据类型转换有啥区别

隐式转换和显式转换及强制转换的区别

隐式等待和显式等待之间的内部工作区别是啥