首页 > 解决方案 > 没有默认构造函数的类对象的值初始化

问题描述

我试图了解C++11 中T()T{}类型的值初始化的确切行为。T让我感到困惑的是这两个摘自http://en.cppreference.com的片段:

值初始化:

值初始化的影响是:[...]

1) 如果 T 是没有默认构造函数的类类型,或者具有用户提供或删除的默认构造函数的类类型,则该对象是默认初始化的;(C++11 起)

[...]

所以我查找了Default-Initialization

默认初始化的效果是:

  • 如果 T 是 [...] 类类型,则考虑构造函数并针对空参数列表进行重载决议。调用选择的构造函数(默认构造函数之一)为新对象提供初始值;

[...]

所以这基本上说如果 T 是一个类类型并且它的隐式默认构造函数不可用,那么对象将通过调用其默认构造函数之一来构造?据我了解,这仅对上述用户提供的默认构造函数有意义;然后,在构造时,只会执行该构造函数中明确说明的内容,并且每个未明确初始化的成员都将默认初始化(如果我在这里错了,请纠正我)。

我的问题:

1)如果没有用户提供的默认构造函数并且没有默认构造函数或者被删除会怎样?我猜代码不会编译。如果这是正确的,那么:

2)还需要明确提及“无默认构造函数”和“已删除默认构造函数”的情况?

标签: c++c++11initializationlanguage-lawyer

解决方案


cppreference 上的措辞似乎与标准中的措辞不符。C++11 8.5/7 [dcl.init]:

对类型对象进行值初始化T意味着:

  • ifT是具有用户提供的构造函数(12.1)的(可能是 cv 限定的)类类型(第 9 条),则调用 for 的默认构造函数(如果没有可访问的默认构造函数T,则初始化格式错误);T
  • ifT是没有用户提供的构造函数的(可能是 cv 限定的)非联合类类型,则该对象被零初始化,并且如果T' 的隐式声明的默认构造函数不平凡,则调用该构造函数。
  • 如果T是数组类型,则每个元素都是值初始化的;
  • 否则,对象被零初始化。

一个值初始化的对象被认为是被构造的,因此受制于适用于“构造的”对象、“构造函数已完成的对象”等的本国际标准的规定,即使没有为对象的构造函数调用构造函数。初始化。

为了比较,这是 C++14 (n4140) 8.5/7 [dcl.init] 中的措辞:

对类型对象进行值初始化T意味着:

  • 如果T是(可能是 cv 限定的)类类型(第 9 条),没有默认构造函数 (12.1) 或用户提供或删除的默认构造函数,则该对象是默认初始化的;
  • ifT是一个(可能是 cv 限定的)类类型,没有用户提供或删除的默认构造函数,则该对象被零初始化并检查默认初始化的语义约束,如果 T有一个非平凡的默认构造函数,则对象是默认初始化的;
  • 如果T是数组类型,则每个元素都是值初始化的;
  • 否则,对象被零初始化。

一个值初始化的对象被认为是被构造的,因此受制于适用于“构造的”对象、“构造函数已完成的对象”等的本国际标准的规定,即使没有为对象的构造函数调用构造函数。初始化。


推荐阅读