杂项临时对象T()

时间:2012-02-19 06:44:54

标签: c++ most-vexing-parse temporary-objects

考虑以下代码:

int main()
{
    int i(6); //this will result in i==6,but consider next initializations

    int j(int()); 

    T * p2 = new T(); 
}

我发现j的值为1,但这应该是0,因为int()是临时值,其值等于0。

此外,new运算符的语法为new typename,但此处T()将是临时对象而非类型名称。

2 个答案:

答案 0 :(得分:4)

int j(int()); 

这不会声明对象。相反,它声明了一个函数,该函数将函数作为参数,并返回int。它作为参数所使用的函数的类型是:

 typedef int (*funtype)();

那是一个返回int的函数,并没有作为参数。

解析这种声明通常称为:


new语法中,T()不会创建临时对象。这不是如何被看到的。相反,您需要查看整个表达式new T(),它首先为类型为T的对象分配内存,然后在该内存中构造对象。如果T是用户定义的类型,则在分配内存后,它会调用默认构造函数来构造对象。

答案 1 :(得分:1)

  

new运算符的语法也是typename * variable_name = new typename,但此处T()将是临时对象,但不是类型名称。

与Most Vexing Parse类似,T()具有不同的含义,具体取决于上下文。它并不总是产生临时的,但通常初始化一些新的匿名对象或子对象。对象可能是

  • 表达式T()中的临时表,
  • 基础子对象,如果T()出现在构造函数中的正文之前,或
  • T()后出现new时指针的指示对象。请注意,指针有一个名称,但该对象是匿名的。

new Tnew T()略有不同:对于某些类型,new T会使值未初始化。 (官方术语是 default-initialization 。)对于基础子对象或临时对象没有相应的语法结构:通过省略初始化器来默认初始化基础子对象,并且不允许临时对象默认初始化。差别很小,因为在所有这些情况下,如果您定义了一个构造函数,并且应始终定义构造函数,并且应始终初始化所有成员。例外是基本类型,例如int和简单结构,例如std::array<char, 1000>

为了安全起见,最好避免new T支持new T()只是为了确保在没有构造函数的情况下将事情很好地归零。