c++ 11使用默认的默认构造函数进行值初始化
C++11 value-initialization with defaulted default constructor
示例如下:
#include <iostream>
struct A {
int z;
A(std::string) {}
A() = default;
};
int main() {
char buf[1000];
std::fill(buf, buf + 1000, 'x');
auto a = new(buf) A{};
std::cerr << "A.z: " << a->z << std::endl;
}
使用GCC 4.8编译输出为零(与Clang 3.4相同)。这似乎表明a
在调用默认构造函数之前被零初始化。
但是根据cppreference.com上的值初始化规则,在调用默认构造函数之前不应该初始化对象。类A
符合c++ 11中的第1点:
1)如果T是具有至少一个用户提供的任意类型构造函数的类类型,则调用默认构造函数。
另一个可能有用的数据点是,如果我们在上面的例子中用A() {}
替换A() = default
,没有像预期的那样发生零初始化。这似乎表明在初始示例中遵循了值初始化的第2点,这是错误的:
2)如果T是一个没有任何用户提供的构造函数的非联合类类型,那么对象将被零初始化,然后调用隐式声明的默认构造函数(除非它是微不足道的)
您引用的c++ 11中值初始化的措辞被认为是有缺陷的,请参阅核心工作组DR 1368和核心工作组DR 1301的决议,该决议更改了措辞(显示添加加粗和删除通过):
value-initialize类型为
T
的对象意味着:
如果
T
是一个(可能是cv合格的)类类型(第9条[class]),其中没有默认构造函数(12.1 [class.ctor])或默认构造函数是用户提供的或已删除的构造函数(12.1 [class.ctor]),则对象是默认初始化的调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);如果
T
是一个(可能是cv限定的)非联合类类型,没有用户提供的或已删除的默认构造函数,则对象是零初始化的,如果T的隐式声明的默认构造函数是T
有一个非简单的默认构造函数,则调用该构造函数。 default-initialized ,
一些编译器——我相信GCC 4.8和clang从3.3开始——已经实现了DR 1301的分辨率
- 使用 std::分配器在 constexpr 中进行默认初始化
- 为什么对象默认初始化,但基元不在C++?
- 为什么std::atomic的默认构造函数不默认初始化底层存储值
- 两个成员,在Base中默认初始化,可能在Derived中非默认初始化
- 默认初始化无法正常工作
- C++11默认初始化/值初始化/直接初始化
- make_shared是否对每个成员变量执行默认初始化(零初始化)
- 是否可以默认初始化具有已删除默认构造函数的类类型
- 对象成员数组C++默认初始化
- POD成员默认初始化无括号
- 如何在不使用 new 的情况下进行默认初始化
- 有没有办法欺骗 std::make_shared 使用默认初始化
- 枚举类默认初始化
- 是默认的构造函数和默认初始化
- 为什么在C 中不允许使用括号的默认初始化
- 默认初始化的含义在C 11中发生了变化
- Main()函数中的默认初始化
- WINHTTP_CURRENT_USER_IE_PROXY_CONFIG默认初始化
- 强制本地变量默认初始化
- 默认初始化混乱