我对值和默认值和零初始化感到非常困惑。尤其是当他们加入不同的标准 C++03 和 C++11 (和 C++14 )时。
我在这里引用并尝试扩展一个非常好的答案 Value-/Default-/Zero-Init C++98 和 C++03 以使其更通用,因为如果有人可以帮助填写需要空白来很好地了解什么时候会发生什么?
简而言之,通过示例的完整见解:
有时 new 运算符返回的内存将被初始化,有时它不会取决于您要更新的类型是 POD (plain old data) 还是包含 POD 成员的类并且正在使用编译器生成的默认构造函数。
- 在 C++1998 中有两种类型的初始化: 零 初始化和 默认初始化
- 在 C++2003 中,添加了第三种初始化类型,即 _值初始化_。
- 在 C++2011/C++2014 中,仅添加了 _列表初始化_,并且 值/默认值/零初始化 的规则发生了一些变化。
认为:
struct A { int m; };
struct B { ~B(); int m; };
struct C { C() : m(){}; ~C(); int m; };
struct D { D(){}; int m; };
struct E { E() = default; int m;}; /** only possible in c++11/14 */
struct F {F(); int m;}; F::F() = default; /** only possible in c++11/14 */
在 C++98 编译器中,应发生以下情况:
new A
- 不确定值(A
是 POD)new A()
- 零初始化new B
- 默认构造(B::m
未初始化,B
非 POD)new B()
- 默认构造(B::m
未初始化)new C
- 默认构造(C::m
是零初始化的,C
是非 POD)new C()
- 默认构造(C::m
是零初始化的)new D
- 默认构造(D::m
未初始化,D
非 POD)new D()
- 默认构造? (D::m
未初始化)
在符合 C++03 的编译器中,事情应该是这样的:
new A
- 不确定值(A
是 POD)new A()
- value-initializeA
,这是零初始化,因为它是一个 POD。new B
- 默认初始化(离开B::m
未初始化,B
是非 POD)new B()
- value-initializesB
对所有字段进行零初始化,因为其默认 ctor 是编译器生成的,而不是用户定义的。new C
- default-initializesC
,它调用默认的ctor。 (C::m
是零初始化,C
是非 POD)new C()
- value-initializesC
,它调用默认的ctor。 (C::m
是零初始化)new D
- 默认构造(D::m
未初始化,D
是非 POD)new D()
- 值初始化D? ,它调用默认的ctor(D::m
未初始化)
斜体值和 ?是不确定性,请帮助纠正这个:-)
在符合 C++11 的编译器中,事情应该是这样的:
??? (如果我从这里开始,请帮忙,它无论如何都会出错)
在符合 C++14 的编译器中,事情应该像这样工作: ??? (如果我从这里开始,请帮忙,无论如何都会出错) (基于答案的草稿)
new A
默认初始化A
,编译器生成。 ctor,(离开A::m
未初始化)(A
是 POD)new A()
- value-initializesA
,这是自 2. point in [dcl.init]/8 以来的零初始化new B
- 默认初始化B
,编译器生成。 ctor,(离开B::m
未初始化)(B
是非 POD)new B()
- value-initializesB
它对所有字段进行零初始化,因为它的默认 ctor 是编译器生成的,而不是用户定义的。new C
- 默认初始化C
,它调用默认的ctor。 (C::m
是零初始化,C
是非 POD)new C()
- value-initializesC
,它调用默认的ctor。 (C::m
是零初始化的)new D
- default-initializesD
(D::m
is uninitialized,D
is non-POD)new D()
- value-initializesD
,它调用默认的ctor(D::m
未初始化)new E
- 默认初始化E
,它调用 comp.将军医生。 (E::m
未初始化,E是非POD)new E()
- value-initializesE
,零初始化E
因为 2 点在 [dcl.init]/8 )new F
- 默认初始化F
,它调用 comp.将军医生。 (F::m
未初始化,F
非POD)new F()
- value-initializesF
, which default-initializesF
since 1. point in [dcl.init]/8 (F
ctor 函数是用户提供的,如果它是用户声明的并且在其第一次声明时没有显式默认或删除。 链接)
原文由 Gabriel 发布,翻译遵循 CC BY-SA 4.0 许可协议
C++14 指定在 [expr.new]/17 中使用
new
创建的对象的初始化(C++11 中的 [expr.new]/15,并且注释不是注释而是规范文本那时):默认初始化在 [dcl.init]/7 中定义(C++11 中的 /6,其措辞本身具有相同的效果):
因此
new A
仅导致A
的默认构造函数被调用,它不会初始化m
。不确定的价值。对于new B
应该相同。new A()
根据[dcl.init]/11(C++11中的/10)解释:现在考虑 [dcl.init]/8(C++11 中的 /7†):
因此
new A()
将零初始化m
。这应该等同于A
和B
。new C
和new C()
将再次默认初始化对象,因为最后引用的第一个要点适用(C 具有用户提供的默认构造函数!)。但是,很明显,现在m
在这两种情况下都在构造函数中进行了初始化。† 好吧,这一段在 C++11 中的措辞略有不同,但不会改变结果: