它已被反复重复,原始类型没有构造函数。例如,当我调用_bar
时,Foo()
未初始化为0:
class Foo{
int _bar;
};
所以显然int()
不是构造函数。但是它的名字是什么?
在这个例子中我会说i
是:(构造?初始化?fooed?)
for(int i{}; i < 13; ++i)
Loki Astari提到here该技术有某种名称。
编辑回复Mike Seymour:
#include <iostream>
using namespace std;
class Foo{
int _bar;
public:
void printBar(){ cout << _bar << endl; }
};
int main()
{
Foo foo;
foo.printBar();
Foo().printBar();
return 0;
}
在Visual Studio 2013上运行此代码会产生:
3382592
3382592
有趣的是gcc 4.8.1产量:
134514651
0
答案 0 :(得分:7)
一遍又一遍地重新说明原始类型没有施工人员。
那是对的。
例如,当我拨打
时,此栏未初始化为0Foo()
是的。 Foo()
指定了值初始化,对于像这样没有用户提供的构造函数的类,它意味着它在初始化其成员之前进行了零初始化。因此_bar
最终得到零值。 (尽管如评论中所述,一个流行的编译器没有正确地对这些类进行值初始化。)
如果您使用默认初始化,则不会初始化。你暂时无法做到这一点;但是声明的变量Foo f;
或new F
的对象将被默认初始化。原始类型的默认初始化没有任何作用,使它们具有不确定的值。
如果类具有用户提供的默认构造函数,并且该构造函数没有专门初始化_bar
,那么它也不会被初始化。同样,它将默认初始化,没有效果。
显然int()不是构造函数。但它的名字是什么?
作为表达式,它是int
类型的值初始化临时值。
从语法上讲,它是&#34;显式类型转换(功能符号)的特例&#34 ;;但是将该术语用于类型转换以外的任何事情都会让人感到困惑。
在这个例子中我会说
i
是:(构造?初始化?fooed?)
初始化。列表初始化(带有空列表),值初始化或零初始化,如果您想更具体。
答案 1 :(得分:5)
以下是int()
的作用(请注意,语法上,int
是简单类型说明符):
[C++11: 5.2.3/1]:
简单类型说明符(7.1.6.2)或 typename-specifier (14.6),后跟带括号的表达式列表在给定表达式列表的情况下构造指定类型的值。如果表达式列表是单个表达式,则类型转换表达式与相应的强制转换表达式(5.4)等效(在定义中,如果在含义中定义)。如果指定的类型是类类型,则类类型应完整。如果表达式列表指定多个值,则类型应为具有适当声明的构造函数的类(8.5,12.1),并且表达式T(x1, x2, ...)
与声明T t(x1, x2, ...)
的效果等效;对于某些发明的临时变量t
,结果是t
作为prvalue的值。
通俗地讲,它代表了一个带有空初始化器的临时int
的构造。不过,我认为你很难找到整个结构的正式名称。
这与int i{}
不同,i
是带有初始化的命名对象的完整声明:您的{{1}}已被声明,构造和初始化
(我不认为这与Loki在对该相关答案的评论中所说的内容有关。)
答案 2 :(得分:-2)
如果需要,可以将其称为伪构造函数,镜像析构函数的术语(伪析构函数调用在C ++11§5.2.4中讨论)。无论如何,int()
是类型int
的默认值,即0。
断言“原始类型没有构造函数”,这是一种相当愚蠢和不切实际的观点。从形式的角度来看,原始类型没有构造函数,但那些坚持该断言的人根本不是正式的。此外,从机器代码的角度来看,他们不会,但对于那些认为断言很重要的人来说,机器代码就像魔术一样。但是,有一点不同,即从机器代码的角度来看,普通的非原始POD类型也缺乏构造函数(它们确实有构造函数),而且我再次怀疑那些将这个断言向前推进的人甚至意识到问题,即我认为他们没有资格发表意见。对于任何绝对的术语性说法都有同样的考虑因素:当你听到这样的说法时,你几乎可以肯定,那些制作它的人几乎不知道所涉及的是什么,而且这种说法只是不切实际的。愚蠢的。
相反,当你听到例如在原始类型的上下文中“构造”或“构造函数调用”,考虑有意义可能意味着什么。形式只是一个定义问题。除了语言律师的讨论之外,重要的是有一个概念模型可行。
以上所述,表达式T()
形式上不是“构造函数”,它不是机器代码级别的构造函数,并且在任何有意义的概念模型中它都不是概念上的构造函数。
它可以是构造函数调用 (实际上,默认构造函数的定义是它可以在源代码级别调用,没有参数),但请注意,构造函数调用没有语法类别。
考虑到上述所有内容,我只是将其称为构造函数调用,当需要更精确时,对于基本类型T
,我将其称为伪构造函数调用强>
如果有人批评我,我会挑战他们进行决斗。
请注意,关于您的陈述
“它一遍又一遍地重复,原始类型没有构造函数。例如,当我调用
时,此栏未初始化为0Foo()
表达式Foo()
执行值初始化,以便将实例(在本例中)归零。
关于没有初始化器的原始类型的本地自动变量初始化缺乏初始化,没有用户定义构造函数的任何类型都有相同的情况,即使有一个使用过的定义构造函数,如果该构造函数没有初始化东西
这有时会让C ++初学者感到震惊。