如果'Test'是一个普通类,那么以下两者之间是否有区别:
Test* test = new Test;
and
Test* test = new Test();
如果'Test'是一个普通类,那么以下两者之间是否有区别:
Test* test = new Test;
and
Test* test = new Test();
当前回答
新事物();是显式的,你想要一个构造函数调用while new Thing;表示您不介意不调用构造函数。
如果在带有用户定义构造函数的结构/类上使用,则没有区别。如果在一个普通的struct/类上调用(例如struct Thing {int i;};)然后new Thing;是像malloc(大小(东西));而new Thing();是像calloc(sizeof(Thing));-它得到零初始化。
问题就在这两者之间:
struct Thingy {
~Thingy(); // No-longer a trivial class
virtual WaxOn();
int i;
};
新事物的行为;vs new Thingy();在这种情况下,在c++ 98和c++ 2003之间变化。详见Michael Burr的解释。
其他回答
假设Test是一个定义了构造函数的类,没有区别。后一种形式更清楚地表明Test的构造函数正在运行,但仅此而已。
不,它们是一样的。但两者之间是有区别的:
Test t; // create a Test called t
and
Test t(); // declare a function called t which returns a Test
这是因为c++(和C)的基本规则:如果某个东西可以是声明,那么它就是声明。
编辑:关于POD和非POD数据的初始化问题,虽然我同意已经说过的一切,但我只是想指出,这些问题只适用于新构造的东西或其他构造方法没有用户定义的构造函数。如果有这样的构造函数,将使用它。99.99%的合理设计的类都有这样的构造函数,因此可以忽略这个问题。
一般来说,第一种情况是默认初始化,第二种情况是值初始化。
例如: 如果是int (POD类型):
Int *test = new Int -我们有任意的初始化,*test的值可以是任意的。 Int *test = new Int () - *test的值为0。
接下来的行为取决于你的测试类型。 我们有不同的情况:测试有默认构造函数,测试生成默认构造函数,测试包含POD成员,非POD成员…
新事物();是显式的,你想要一个构造函数调用while new Thing;表示您不介意不调用构造函数。
如果在带有用户定义构造函数的结构/类上使用,则没有区别。如果在一个普通的struct/类上调用(例如struct Thing {int i;};)然后new Thing;是像malloc(大小(东西));而new Thing();是像calloc(sizeof(Thing));-它得到零初始化。
问题就在这两者之间:
struct Thingy {
~Thingy(); // No-longer a trivial class
virtual WaxOn();
int i;
};
新事物的行为;vs new Thingy();在这种情况下,在c++ 98和c++ 2003之间变化。详见Michael Burr的解释。
new的规则类似于初始化具有自动存储持续时间的对象时所发生的情况(尽管由于令人烦恼的解析,语法可能略有不同)。
如果我说:
int my_int; // default-initialize → indeterminate (non-class type)
那么my_int有一个不确定的值,因为它是非类类型。或者,我可以像这样对my_int进行值初始化(对于非类类型,是零初始化):
int my_int{}; // value-initialize → zero-initialize (non-class type)
(当然,我不能使用(),因为这将是一个函数声明,但int()的工作原理与int{}相同,可以构造一个临时。)
然而,对于类类型:
Thing my_thing; // default-initialize → default ctor (class type)
Thing my_thing{}; // value-initialize → default-initialize → default ctor (class type)
调用默认构造函数来创建Thing,没有异常。
所以,规则或多或少是:
Is it a class type? YES: The default constructor is called, regardless of whether it is value-initialized (with {}) or default-initialized (without {}). (There is some additional prior zeroing behavior with value-initialization, but the default constructor is always given the final say.) NO: Were {} used? YES: The object is value-initialized, which, for non-class types, more or less just zero-initializes. NO: The object is default-initialized, which, for non-class types, leaves it with an indeterminate value (it effectively isn't initialized).
这些规则精确地转换为新语法,添加的规则()可以代替{},因为new永远不会被解析为函数声明。所以:
int* my_new_int = new int; // default-initialize → indeterminate (non-class type)
Thing* my_new_thing = new Thing; // default-initialize → default ctor (class type)
int* my_new_zeroed_int = new int(); // value-initialize → zero-initialize (non-class type)
my_new_zeroed_int = new int{}; // ditto
my_new_thing = new Thing(); // value-initialize → default-initialize → default ctor (class type)
(这个答案包含了c++ 11中概念上的变化,上面的答案目前没有;值得注意的是,一个新的标量或POD实例将以一个不确定的值结束,现在技术上是默认初始化的(对于POD类型,技术上调用一个普通的默认构造函数)。虽然这并没有引起行为上的实际变化,但它确实在一定程度上简化了规则。)