在下面的例子中:
#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 编译 outputs zero (与 Clang 3.4 的行为相同)。这似乎表明 a
在调用默认构造函数之前被零初始化。
但根据value-initialization rules on cppreference.com ,对象不应在默认构造函数调用之前初始化。 A
类符合 C++11 下的要点 #1:
1) If T is a class type with at least one user-provided constructor of any kind, the default constructor is called.
另一个可能有用的数据点是,如果我们在上面的示例中将 A() = default
替换为 A() {}
,no zero-initialization happens正如预期的那样。这似乎表明在初始示例中遵循了值初始化的要点#2,这是错误的:
2) If T is an non-union class type without any user-provided constructors, then the object is zero-initialized and then the implicitly-declared default constructor is called (unless it's trivial)
最佳答案
您在 C++11 中为值初始化引用的措辞被认为是有缺陷的,请参阅 Core Working Group DR 1368和 Core Working Group DR 1301 中的决议改变了措辞(用粗体显示添加,用删除线显示删除):
To value-initialize an object of type
T
means:
if
T
is a (possibly cv-qualified) class type (Clause 9 [class]) with either no default constructor (12.1 [class.ctor]) or a default constructor that is user-provided or deletedconstructor (12.1 [class.ctor]), then the object is default-initializeddefault constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);if
T
is a (possibly cv-qualified) non-union class type without a user-provided or deleted default constructor, then the object is zero-initialized and, ifT's implicitly-declared default constructor isT
has a non-trivial default constructor,that constructor is called.default-initialized;
一些编译器——我相信 GCC 4.8 和自 3.3ish 以来的 clang——已经实现了 DR 1301 的决议。
关于使用默认默认构造函数的 C++11 值初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24043897/