C++ 中的堆栈对象创建- 替代语法

发布于 2024-11-17 09:00:18 字数 641 浏览 2 评论 0原文

可能的重复:
以下短语的含义是什么在 C++ 中:零初始化、默认初始化和值初始化?

我对 C++ 中的一个问题感到困惑。

当使用默认构造函数在堆栈上创建对象时,我认为以下两种语法符号中的任何一个都会给出相同的结果:

class MyClass { public: int i; }
int main()
{
  MyClass a = MyClass();
  MyClass b;
}

但是,第一个语法将字段初始化为零,而第二个语法使字段保持未初始化。所以我的问题是:

  1. 为什么会这样?我认为 C++ 中的字段不应该自动初始化。
  2. 这两种语法之间还有其他差异吗?
  3. 这些语法变体是否有单独的名称来相互区分?

我目前正在使用 Microsoft Visual C++ 2010 Express。 谢谢!

Possible Duplicate:
What do the following phrases mean in C++: zero-, default- and value-initialization?

I am confused about an issue in C++.

When creating an object on the stack using the default constructor, I thought either one of the following two syntax notations would give the same result:

class MyClass { public: int i; }
int main()
{
  MyClass a = MyClass();
  MyClass b;
}

However, the first syntax initializes the field to zero, whereas the second one leaves the field uninitialized. So my questions are:

  1. Why is this so? I thought fields in C++ were not supposed to be automatically initialized.
  2. Is there any other differences between the two syntaxes?
  3. Do these syntax variations have separate names to distinguish them from each other?

I’m currently using Microsoft Visual C++ 2010 Express.
Thanks!

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

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

发布评论

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

评论(2

冰雪梦之恋 2024-11-24 09:00:18

首先,您从 MyClass值初始化实例中复制初始化a。来自 C++03 标准,§8.5/7:

如果对象的初始值设定项是一组空括号,即 (),则应进行值初始化。

从 §8.5/5 开始:

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

  • 如果 T 是具有用户声明的构造函数的类类型,则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数);
  • 如果 T 是没有用户声明的构造函数的非联合类类型,则 T 的每个非静态数据成员和基类组件已初始化值;
  • 如果T是数组类型,则每个元素都是值初始化的;
  • 否则,对象将被零初始化

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

  • 如果 T 是标量类型,则将对象设置为转换为 T0(零)值;
  • 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都被零初始化;
  • 如果T是联合类型,则对象的第一个命名数据成员被零初始化;
  • 如果T是数组类型,则每个元素都初始化为零;
  • 如果 T 是引用类型,则不执行初始化。

在第二种情况下,如果 MyClass 不是 POD 类型,则以某种方式声明 b,使其默认初始化—— §8.5/5:

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

  • 如果 T 是非 POD 类类型,则调用 T 的默认构造函数(如果T 没有可访问的默认构造函数);
  • 如果T是数组类型,则每个元素都默认初始化;
  • 否则,该对象将被零初始化。

但是,由于 MyClass 是 POD 类型,因此 b 未初始化 - §8.5/9:

如果没有为对象指定初始化程序,并且该对象属于(可能是 cv 限定的)非 POD 类类型(或其数组),则该对象应默认初始化;如果对象是 const 限定类型,则底层类类型应具有用户声明的默认构造函数。 否则,如果没有为非静态对象指定初始值设定项,则该对象及其子对象(如果有)将具有不确定的初始值;如果对象或其任何子对象是 const 限定类型,则程序格式错误。

In the first, you copy-initialize a from a value-initialized instance of MyClass. From the C++03 standard, §8.5/7:

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

And from §8.5/5:

To value-initialize an object of type T means:

  • if T is a class type with a user-declared constructor, 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

To zero-initialize an object of type T means:

  • if T is a scalar type, 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 zero-initialized;
  • if T is a union type, the object’s first named data member) is zero-initialized;
  • if T is an array type, each element is zero-initialized;
  • if T is a reference type, no initialization is performed.

In the second, you declare b in a manner that would cause it to be default-initialized if MyClass were not a POD type -- §8.5/5:

To default-initialize an object of type T means:

  • if T is a non-POD class type, 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.

However, because MyClass is a POD type, b is uninitialized -- §8.5/9:

If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a non-static object, the object and its subobjects, if any, have an indeterminate initial value; if the object or any of its subobjects are of const-qualified type, the program is ill-formed.

深爱成瘾 2024-11-24 09:00:18

基本上,这是该语言中的一个(相对)简单的 WTF,默认情况下不会初始化原始类型。第一个语法显式地初始化它们,而第二个则没有。用户定义的类型总是会被初始化,所以只有在构造函数中没有初始化它才有意义,如果不调用需要它们的UDT的init函数,就会出错。

不做任何疯狂事情的​​ UDT 不应该需要第一种语法,使用第二种语法是正常的。

Basically, this is a (relatively) simple WTF in the language, where primitive types will not be initialized by default. The first syntax explicitly initializes them- the second doesn't. User-defined types will always be initialized, so it's only meaningful if you don't initialize it in the constructor, and it will be an error if you don't call the init functions of UDTs that need them.

UDTs that do not do anything insane should not require the first syntax and it's normal to use the second.

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