在C++中,下面的代码是如何工作的

In C++, how does the following code works?

本文关键字:何工作 工作 代码 C++      更新时间:2023-10-16

可能重复:
类型名称后面的括号与new有区别吗?

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

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

如果有用户声明的默认构造函数

这个怎么样:

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

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

对于具有构造函数的struct s和class es,使用空括号之间的唯一区别是基元类型,如果有括号,则为零初始化,否则为未初始化

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

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

相反,如果指定圆括号,则始终执行默认初始化,对于基元类型,这意味着零初始化。

完整的故事在§5.3.4¶15中进行了解释;§8.5中涵盖了默认初始化。


相关标准报价:

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

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

(§5.3.4¶15(

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

Test t1;
Test t3 = Test();

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