【发布时间】:2015-06-28 05:53:29
【问题描述】:
我对值、默认值和零初始化感到非常困惑。 尤其是当他们加入不同的标准C++03和C++11(和C++14)时。 p>
我在这里引用并尝试扩展一个非常好的答案Value-/Default-/Zero- Init C++98 and C++03 以使其更通用,因为如果有人可以帮助填补所需的空白以很好地了解何时会发生什么,它将帮助很多用户?
简而言之,通过示例获得完整见解:
有时 new 操作符返回的内存会被初始化,有时它不会取决于你要更新的类型是POD (plain old data),或者它是否是一个包含 POD 成员的类并且正在使用编译器生成的默认构造函数。
- 在 C++1998 中有 2 种初始化类型:zero- 和 default-initialization
- 在 C++2003 中添加了第三种初始化类型,值初始化。
- 在 C++2011/C++2014 中仅添加了 list-initialization 和 value-/default-/zero-initialization 的规则 有点改变。
假设:
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- 默认初始化C,它调用默认 ctor。 (C::m是零初始化,C是非 POD) -
new C()- 值初始化C,它调用默认 ctor。 (C::m初始化为零) -
new D- 默认构造(D::m未初始化,D非 POD) -
new D()- value-initializes D?,它调用了默认的 ctor(D::m未初始化)
斜体值和 ?是不确定性,请帮助纠正这个:-)
在符合 C++11 的编译器中,事情应该是这样的:
??? (请帮忙,如果我从这里开始,无论如何都会出错)
在符合 C++14 的编译器中,事情应该是这样的: ??? (如果我从这里开始,请帮忙,它无论如何都会出错) (根据答案草稿)
-
new A- 默认初始化A,编译器生成。 ctor,(离开A::m未初始化)(A是 POD) -
new A()- value-initializesA,这是自 2. 以来的零初始化。指向 [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()- 值初始化C,它调用默认的ctor。 (C::m初始化为零) -
new D- 默认初始化D(D::m未初始化,D非 POD) -
new D()- value-initializesD,调用默认ctor(D::m未初始化) -
new E- 默认初始化E,它调用 comp.将军医生。 (E::m未初始化,E 非 POD) -
new E()- value-initializesE,从 [dcl.init]/8 的 2 点开始将E初始化为零) -
new F- 默认初始化F,它调用 comp.将军医生。 (F::m未初始化,F非 POD) -
new F()- value-initializesF, default-initializesF因为 1. 指向 [dcl.init]/8 (@987654407 @ctor 函数是用户提供的,如果它是用户声明的,并且在第一次声明时没有显式默认或删除。Link)
【问题讨论】:
-
据我所知,在这些示例中,C++98 和 C++03 之间只有区别。该问题似乎在N1161(该文档有后续修订版)和CWG DR #178 中有所描述。由于 POD 的新特性和新规范,措辞需要在 C++11 中更改,并且由于 C++11 措辞中的缺陷,它在 C++14 中再次更改,但是这些情况下的效果不会改变。
-
虽然很无聊,但
struct D { D() {}; int m; };可能值得包含在您的列表中。 -
有一张很好的令人不安的海报,它把这个混乱带到了重点:randomcat.org/cpp_initialization/initialization.png
标签: c++ c++11 c++14 c++03 c++98