types名称后的圆括号与新的有什么不同?
如果“testing”是一个普通的类,是否有任何区别:
Test* test = new Test;
和
Test* test = new Test();
让我们来迂回,因为有实际上可能影响你的代码行为的差异。 以下大部分内容来自对“旧新事物”文章的评论 。
有时,新运算符返回的内存将被初始化,有时它不会取决于新build的types是POD(普通旧数据) ,还是包含POD成员的类,并且正在使用编译器生成的默认构造函数。
- 在C ++ 1998中有两种types的初始化:零和默认
- 在C ++ 2003中第三种types的初始化,增加了值初始化。
承担:
struct A { int m; }; // POD struct B { ~B(); int m; }; // non-POD, compiler generated default ctor struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
在C ++ 98编译器中,应该发生以下情况:
- 新的A – 不确定的价值
-
新的A() – 零初始化
-
新的B – 默认构造(B :: m未初始化)
-
新的B() – 默认构造(B :: m未初始化)
-
新的C – 默认构造(C :: m是零初始化)
- 新的C() – 默认构造(C :: m是零初始化的)
在符合C ++ 03的编译器中,事情应该像这样工作:
- 新的A – 不确定的价值
-
新的A() – 值初始化A,这是零初始化,因为它是一个POD。
-
新的B – 默认初始化(使B :: m未初始化)
-
新的B() – 值初始化B零初始化所有领域,因为它的默认ctor是编译器生成而不是用户定义。
-
新C – 默认初始化C,它调用默认的ctor。
- 新的C() – 值 – 初始化C,它调用默认的ctor。
所以在C ++的所有版本中,“ new A
”和“ new A()
”都有区别,因为A是POD。
对于“ new B()
”,C ++ 98和C ++ 03之间的行为有所不同。
这是C ++的尘土飞扬的angular落之一,可以让你疯狂。 在构build一个对象的时候,有时你需要/需要这些对象,有时你绝对不能拥有它们,有时候并不重要。
new Thing();
明确的说,你想要一个叫做new Thing;
的构造函数new Thing;
被认为暗示你不介意构造函数没有被调用。
如果在用户定义的构造函数的struct / class上使用,则没有区别。 如果调用一个微不足道的结构/类(例如struct Thing { int i; };
)然后new Thing;
就像malloc(sizeof(Thing));
而new Thing();
就像calloc(sizeof(Thing));
– 它初始化为零。
这个问题在于:
struct Thingy { ~Thingy(); // No-longer a trivial class virtual WaxOn(); int i; };
new Thingy;
的行为new Thingy;
vs new Thingy();
在这种情况下在C ++ 98和C ++ 2003之间进行了更改。 见迈克尔伯尔的解释如何和为什么。
一般情况下,我们有第一种情况下的默认初始化和第二种情况下的值初始化。
例如:在int(PODtypes)的情况下:
-
int* test = new int
– 我们有任何初始化和* test的值都可以。 -
int* test = new int()
– * test将有0值。
下一个行为取决于你的typestesting。 我们有不同的情况:testing有defult构造函数,testing产生了默认的构造函数,testing包含POD成员,非POD成员…
不,他们是一样的。 但是有一个区别:
Test t; // create a Test called t
和
Test t(); // declare a function called t which returns a Test
这是因为基本的C ++(和C)规则:如果有可能是一个声明,那么它是一个声明。
编辑:重新初始化有关POD和非POD数据的问题,虽然我同意所有的说法,我只想指出,这些问题只适用于新的东西或以其他方式构build的东西没有用户定义的构造函数。 如果有这样的构造函数将被使用。 对于99.99%的devise合理的类,将会有这样的构造函数,所以这些问题可以被忽略。
假设Test是一个具有定义的构造函数的类,没有什么区别。 后一种forms使得Test的构造函数运行起来更清楚一点,但就是这样。