【问题标题】:In C++, how does the following code works? [duplicate]在 C++ 中,以下代码如何工作? [复制]
【发布时间】:2011-08-18 17:57:09
【问题描述】:

可能重复:
Do the parentheses after the type name make a difference with new?

以下代码执行了哪些操作:

Test *t1 = new Test; // there is no () after new Test;

是否有用户声明的默认构造函数

这个呢:

Test *t2 = new Test(); // there is () after new Test;

【问题讨论】:

    标签: c++


    【解决方案1】:

    它们是等价的,在这两种情况下都会调用不带参数的 ctor。

    【讨论】:

    【解决方案2】:

    对于具有构造函数的structs 和classes,它是相同的,使用空括号的唯一区别是对于原始类型,如果括号在那里,则初始化为零,而它们否则未初始化。

    实际上,比这更复杂;如果省略括号:

    • 非 POD 的 classes 和 structs 是默认初始化的,这实际上意味着调用了它们的构造函数;
    • POD(尤其是原始类型)未初始化;

    如果您指定括号,则始终执行默认初始化,对于原始类型,这意味着零初始化。

    完整的故事在 §5.3.4 ¶15 中有解释; §8.5 介绍了默认初始化。


    相关标准报价:

    创建一个新表达式 T 类型的对象初始化 对象如下:

    • 如果省略了 new-initializer:
      • 如果 T 是(可能是 cv 限定的)非 POD 类类型(或 数组),对象是 默认初始化 (8.5) 如果 Tconst-限定类型,底层 类类型应具有用户声明的 默认构造函数。
      • 否则,创建的对象具有不确定的值。如果Tconst-qualified 类型,或(可能 cv 限定)POD 类类型(或数组) 其中)包含(直接或 间接)成员 const 限定类型,程序是 格式不正确;
    • 如果新初始化程序的形式为(),则默认初始化 应执行 (8.5);
    • 如果 new-initializer 的形式为 (expression-list) 并且 T 是 类类型,适当的 构造函数被调用,使用 表达式列表作为参数 (8.5);
    • 如果 new-initializer 是 (expression-list) 形式并且 T 是 算术、枚举、指针或 指向成员类型的指针和 表达式列表正好包含一个 表达式,那么对象是 初始化为(可能 转换的) 表达式的值 (8.5); — 否则新表达式 格式不正确。

    (§5.3.4 ¶15)

    【讨论】:

      【解决方案3】:

      它会自动调用默认构造函数。你也可能遇到这些:

      Test t1;
      Test t3 = Test();
      

      它们都具有调用默认构造函数的相同效果。

      【讨论】:

      • 第二种情况与其他情况完全不同:它声明了一个不接收参数并返回Test的函数。其他两种情况再次不同,第一个“默认初始化”t1,最后一个“值初始化”临时和复制构造t3。默认初始化和值初始化之间的区别可以通过 POD 类型看到(默认 = 未初始化,值 = 零初始化),虽然大多数/所有编译器都会忽略副本,但编译器必须检查是否有可用的副本 -构造函数(如果它被声明为私有将失败)
      • @David,+1 感谢您指出,您对第二种情况是正确的,我编辑了我的帖子。但是关于第一个,我不认为有任何东西是未初始化的对象,因为构造函数总是被调用,所以如果默认构造函数被重载,它就会被初始化。我并不是要提供这些示例与所讨论的示例相同,只是说他可能会遇到这些,并且这些都是调用默认构造函数的方法,如果我错了,请纠正我。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      • 1970-01-01
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多