【问题标题】:Is new int[10]() valid c++?new int[10]() 是有效的 C++ 吗?
【发布时间】:2010-03-18 08:35:20
【问题描述】:

在尝试回答 this 问题时,我发现代码 int* p = new int[10](); 可以使用 VC9 编译器很好地编译并将整数初始化为 0。所以我的问题是:

  1. 首先是这个有效的 C++ 还是 是微软的扩展吗?
  2. 是否保证初始化所有 数组的元素?
  3. 另外,如果我 做new int; 还是new int();?做 后者保证初始化 变量?

【问题讨论】:

    标签: c++ arrays constructor initialization


    【解决方案1】:

    首先,这是有效的 C++ 还是微软的扩展?

    在C++中有效,标准相关部分为5.3.4,第一段包含语法

    是否保证初始化数组的所有元素?

    是的。第 5.3.4/15 段指出

    创建 T 类型对象的新表达式按如下方式初始化该对象:

    ...

    • 如果 new-initializer 的形式为 (),则该项为值初始化 (8.5)

    为 POD 初始化的值意味着零初始化。

    另外,如果我做 new int; 有什么不同吗?还是新的 int();?后者保证初始化变量吗?

    是的,它们是不同的。根据上面的引用new int() 将对整数进行零初始化。在同一段落的前一个块中:

    如果省略了 new-initializer:

    • 如果 T 是(可能是 cv 限定的)非 POD 类类型(或其数组),则该对象是默认初始化的 (8.5)。如果 T 是 const 限定类型,则基础类类型应具有用户声明的默认构造函数。

    • 否则,创建的对象具有不确定的值。如果 T 是一个 const 限定类型,或者一个(可能是 cv 限定)POD 类类型(或其数组),包含(直接或间接)一个 const 限定类型的成员,则程序是非良构的;

    所以new int 不会初始化内存。

    【讨论】:

      【解决方案2】:

      从标准。 “默认初始化 T 类型的对象意味着: -- 如果 T 是非 POD 类类型 【类似vector的情况】,调用T的默认构造函数。”

      构造函数符号T() 用于表示类型 T 的默认值,对于内置类型和用户定义类型的默认构造函数,它为零。构造 POD() 根据标准产生值初始化,这导致所有成员和子成员被默认构造或零初始化。

      这就是为什么您的声明是合法的,但它是否按照标准初始化为零;需要一些详细的查找恕我直言。

      但是,我在标准中找不到它定义 内置类型的默认构造的含义

      编辑:-

      struct S { int x; };
      
      void f () {
         S s1;       // s1.x is uninitialized here
         S s2 = S(); // s2.x is zero here
      }
      

      我认为我们经常对应用于内置类型的默认构造的含义做出自己的解释;因为 C++ 标准没有定义它(至少我找不到它),我记得 StroustrupJosuttis 说这意味着 T() 被描述为价值对于内置类型,初始化是“零转换为类型 T”。

      由于int* 是一个内置类型,它被初始化为零。

      但我真的不确定。

      【讨论】:

      • 这真的是一个初始化列表吗?我以为那些 { 1,2,3 } ?
      • @Abhay:§8.5 与问题无关。正如 Marcus Lindblom 正确指出的那样,初始化列表的形式为 { 1,2,3 } 并且不能(在当前标准中)与 new 表达式一起使用。新表达式中的初始化规则属于 §5.3.4 [expr.new]
      • @dribeas:是的,你说得对,编辑了这篇文章,但我在 OP 分配数组以获取初始化部分的上下文中冒险进入它。我的坏:-(
      • 在编辑中:该标准对所有初始化规则都有完整的定义,即使它们非常复杂且难以遵循。 §8.5/9 指出,如果没有为非静态 POD 对象指定初始化程序,它将具有不确定的初始值(我相信这就是您所说的“默认构造”,这与默认初始化不同)。 §8.5/7 指出,作为空括号集的初始化程序意味着 value-initialize
      • 顺便说一句,对于 POD 类型的 default-initialize 意味着对于 POD 类型的 zero-initialize,即使 int x;
      【解决方案3】:
      1. 根据第 5.3.4/1 段,这是有效的 C++,由于特殊格式,这里很难引用。

      2. 根据 5.3.4/15,如果使用 form (),则项目是值初始化的,请参阅第 8.5 段,但简短的回答是肯定的。

      3. 是的,在第一种情况下存在差异,变量未初始化值,可以是任何值,在第二种情况下,它的值已初始化并且为零。

      【讨论】:

        【解决方案4】:

        如果我可以猜测一下(如果我错了,我相信我会得到纠正):

        后者 () 进行值初始化(在标准术语中称为),这使得整数在这种情况下具有值 0。

        这是对标准(C++03?)的一个相当新的补充,因此旧的编译器可能不支持它,并且未初始化。

        我记得在从 MSVS 2003 切换到 2005(我认为)时收到了很多警告,编译器说“这个成员现在将被零初始化,以前不是”。

        【讨论】:

        • 没有 C++03 标准这样的东西,尽管 MSVS 确实变得更加符合每个版本的标准。
        • @Gorpik,目前的标准是 ISO/IEC 14882:2003,如果你使用当年命名标准的通用规则,那将是 c++03,即使这不是正确的名称(因为下一个标准肯定不会被称为 c++11,即使大多数人会这样称呼它)
        • 对不起,你是对的。我忘记了 2003 年发布的标准修正案。
        猜你喜欢
        • 1970-01-01
        • 2011-02-20
        • 2019-01-11
        • 1970-01-01
        • 2018-03-20
        • 2017-10-17
        • 2018-10-21
        • 2010-11-08
        相关资源
        最近更新 更多