C++ 杂项临时对象T()
考虑以下代码:C++ 杂项临时对象T(),c++,most-vexing-parse,temporary-objects,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操作符的语法是newtypename,但是这里的T()将是一个临时对象,而不是类型名 int j(int()); 这不会声明对
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
操作符的语法是newtypename
,但是这里的T()
将是一个临时对象,而不是类型名
int j(int());
这不会声明对象。相反,它声明了一个以函数为参数的函数,并返回int
。作为参数的函数类型如下:
typedef int (*funtype)();
也就是说,一个返回int
,并且不接受任何参数的函数
这种声明的解析通常称为:
在
new
语法中,T()
不会创建临时对象。这不是我们应该看到的。相反,您必须查看整个表达式new T()
,它首先为T
类型的对象分配内存,然后在该内存中构造对象。如果T
是用户定义的类型,则在分配内存后,它将调用默认构造函数来构造对象
这不会声明对象。相反,它声明了一个以函数为参数的函数,并返回int
。作为参数的函数类型如下:
typedef int (*funtype)();
也就是说,一个返回int
,并且不接受任何参数的函数
这种声明的解析通常称为:
在
new
语法中,T()
不会创建临时对象。这不是我们应该看到的。相反,您必须查看整个表达式new T()
,它首先为T
类型的对象分配内存,然后在该内存中构造对象。如果T
是用户定义的类型,则在分配内存后,它将调用默认构造函数来构造对象
新操作符的语法也是typename*variable_name=new typename,但这里的T()
将是一个临时对象,而不是类型名
int j(int());
与最麻烦的解析类似,T()
根据上下文具有不同的含义。它并不总是生成临时对象,但通常会初始化一些新的匿名对象或子对象。对象可能是
- 表达式中存在临时if
T()
- 如果
出现在构造函数的主体之前,则为基本子对象,或者T()
- 如果
出现在T()
之后,则指针的引用。请注意,指针有名称,但对象是匿名的new
new T
和new T()
做的事情稍有不同:对于某些类型,new T
使值未初始化。(官方术语是默认初始化。)基本子对象或临时对象没有相应的语法结构:基本子对象通过省略初始值设定项进行默认初始化,临时对象不允许进行默认初始化。区别很小,因为在所有这些情况下,如果您定义了构造函数,就会调用构造函数,并且应该始终定义构造函数,并且它应该始终初始化所有成员。例外情况是基本类型,如int
和简单结构,如std::array
为了安全起见,最好避免使用new T
,而使用new T()
,这样可以确保在没有构造函数的情况下很好地将事情归零
新操作符的语法也是typename*variable_name=new typename,但这里的T()
将是一个临时对象,而不是类型名
int j(int());
与最麻烦的解析类似,T()
根据上下文具有不同的含义。它并不总是生成临时对象,但通常会初始化一些新的匿名对象或子对象。对象可能是
- 表达式中存在临时if
T()
- 如果
出现在构造函数的主体之前,则为基本子对象,或者T()
- 如果
出现在T()
之后,则指针的引用。请注意,指针有名称,但对象是匿名的new
new T
和new T()
做的事情稍有不同:对于某些类型,new T
使值未初始化。(官方术语是默认初始化。)基本子对象或临时对象没有相应的语法结构:基本子对象通过省略初始值设定项进行默认初始化,临时对象不允许进行默认初始化。区别很小,因为在所有这些情况下,如果您定义了构造函数,就会调用构造函数,并且应该始终定义构造函数,并且它应该始终初始化所有成员。例外情况是基本类型,如int
和简单结构,如std::array
为了安全起见,最好避免使用
new T
而使用new T()
,这只是为了确保在没有构造函数的情况下可以很好地归零。解决方法是使用额外的括号使其成为无效的函数声明:int j((int())代码>,或避免语法:intj=int()
@nawaz:那么secoond question呢?解决方法是使用额外的括号使其成为无效的函数声明:intj((int())代码>,或避免语法:intj=int()
@nawaz:还有第二个问题呢?你很困惑,new T()
会动态分配一个T
对象并初始化它,它不会创建一个临时值。你到底想做什么。这应该是关闭的,现在没有问题,如果添加了一个问题,它将是纳瓦兹答案中链接的复制品,或者其他,事实上,TJ只是问了其中一个问题