考虑以下代码:
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()
将是临时对象而非类型名称。
答案 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 T
和new T()
略有不同:对于某些类型,new T
会使值未初始化。 (官方术语是 default-initialization 。)对于基础子对象或临时对象没有相应的语法结构:通过省略初始化器来默认初始化基础子对象,并且不允许临时对象默认初始化。差别很小,因为在所有这些情况下,如果您定义了一个构造函数将,并且应始终定义构造函数,并且应始终初始化所有成员。例外是基本类型,例如int
和简单结构,例如std::array<char, 1000>
。
为了安全起见,最好避免new T
支持new T()
只是为了确保在没有构造函数的情况下将事情很好地归零。