C++03 中默认初始化和值初始化之间的区别?

发布于 2024-11-29 15:44:47 字数 675 浏览 0 评论 0原文

我一直认为创建一个新对象总是会调用对象的默认构造函数,而构造函数是显式的还是由编译器自动生成的都没有区别。根据这个高度被认为是另一个问题的答案,这在 C++98 和 C++03 之间发生了微妙的变化,现在的工作方式如下:

struct B { ~B(); int m; }; // non-POD, compiler generated default ctor 
new B;   // default-initializes (leaves B::m uninitialized)
new B(); // value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

谁能告诉我:

  1. 为什么标准发生了变化,即这有什么好处给予或现在可能以前没有的东西;
  2. 术语“默认初始化”和“值初始化”到底代表什么?
  3. 标准的相关部分是什么?

I had always thought that creating a new object would always call the default constructor on an object, and whether the constructor was explicit or automatically generated by the compiler made no difference. According to this highly regarded answer to a different question, this changed in a subtle way between C++98 and C++03 and now works like so:

struct B { ~B(); int m; }; // non-POD, compiler generated default ctor 
new B;   // default-initializes (leaves B::m uninitialized)
new B(); // value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

Can anyone tell me:

  1. Why was the standard changed, i.e. what advantage does this give or what is now possible that wasn't before;
  2. What exacly do the terms "default-initialize" and "value-initialize" represent?
  3. What's the relevant part of the standard?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

向日葵 2024-12-06 15:44:47

我不知道更改的基本原理是什么(或者之前的标准是怎样的),但是关于它是如何的,基本上默认初始化要么调用用户定义的构造函数,要么什么也不做(很多手- 此处挥动:这会递归地应用于每个子对象,这意味着具有默认构造函数的子对象将被初始化,没有用户定义构造函数的子对象将保持未初始化状态)。

这属于“只为你想要的东西付费”的语言哲学,并且在所有与 C 兼容的类型中与 C 兼容。另一方面,您可以请求值初始化,这相当于为将其初始化为0的对象调用默认构造函数 code> 转换为其余子对象的适当类型。

这在第 8.5 节初始化器中进行了描述,并且导航起来并不简单。 零初始化默认初始化值初始化的定义是第5段:

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

—如果 T 是标量类型 (3.9),则将对象设置为转换为 T 的 0(零)值;

——如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都被零初始化;

—如果 T 是联合类型,则对象的第一个命名数据成员89) 为零初始化;

——如果T是数组类型,则每个元素都初始化为零;

—如果 T 是引用类型,则不执行初始化。

默认初始化 T 类型的对象意味着:

——如果 T 是非 POD 类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化格式错误);

——如果T是数组类型,则每个元素默认初始化;

—否则,该对象将被零初始化。

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

—如果 T 是具有用户声明的构造函数 (12.1) 的类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化格式错误);< /p>

—如果 T 是没有用户声明的构造函数的非联合类类型,则 T 的每个非静态数据成员和基类组件都进行值初始化;

——如果T是数组类型,那么每个元素都是值初始化的;

—否则,该对象将被零初始化

调用引用类型实体的默认初始化或值初始化的程序格式不正确。如果 T 是 cv 限定类型,则 T 的 cv 非限定版本将用于这些零初始化、默认初始化和值初始化的定义。

I do not know what the rationales around the change (or how the standard was before), but on how it is, basically default-initialization is either calling a user defined constructor or doing nothing (lots of hand-waving here: this is recursively applied to each subobject, which means that the subobjects with a default constructor will be initialized, the subobjects with no user defined constructors will be left uninitialized).

This falls within the only pay for what you want philosophy of the language and is compatible with C in all the types that are C compatible. On the other hand, you can request value-initialization, and that is the equivalent to calling the default constructor for objects that have it or initializing to 0 converted to the appropriate type for the rest of the subobjects.

This is described in §8.5 Initializers, and it is not trivial to navigate through. The definitions for zero-initialize, default-initialize and value-initialize are the 5th paragraph:

To zero-initialize an object of type T means:

— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;

— if T is a non-union class type, each nonstatic data member and each base-class subobject is zeroinitialized;

— if T is a union type, the object’s first named data member89) is zero-initialized;

— if T is an array type, each element is zero-initialized;

— if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:

— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is an array type, each element is default-initialized;

— otherwise, the object is zero-initialized.

To value-initialize an object of type T means:

— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;

— if T is an array type, then each element is value-initialized;

— otherwise, the object is zero-initialized

A program that calls for default-initialization or value-initialization of an entity of reference type is illformed. If T is a cv-qualified type, the cv-unqualified version of T is used for these definitions of zeroinitialization, default-initialization, and value-initialization.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文