0

考虑这段代码:

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

    int j(int()); 

    T * p2 = new T(); 
}

我发现 的值为j1,但这应该是 0,因为int()它是一个值等于 0 的临时值。

此外,运算符的语法newnew typename,但这里T()将是一个临时对象而不是类型名称。

4

2 回答 2

4
int j(int()); 

这没有声明一个对象。相反,它声明了一个函数,该函数将函数作为参数,并返回int. 它作为参数的函数类型是这样的:

 typedef int (*funtype)();

也就是说,一个函数返回int,并且不接受任何参数。

这种声明的解析通常称为:


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

于 2012-02-19T06:52:59.053 回答
1

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

与 Most Vexing Parse 类似,T()根据上下文有不同的含义。它并不总是产生临时的,但一般会初始化一些新的匿名对象或子对象。对象可能是

  • 临时 ifT()在表达式中,
  • T()如果在构造函数中出现在主体之前,则基子对象,或者
  • T()如果出现在 之后,则指针的所指对象new。请注意,指针有名称,但对象是匿名的。

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

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

于 2012-02-19T07:30:28.753 回答