如果'Test'是一个普通的类,那么之间有什么区别:
Test* test = new Test;
和
Test* test = new Test();
Michael Burr.. 926
让我们变得迂腐,因为存在实际上会影响代码行为的差异.以下大部分内容来自对"Old New Thing"文章的评论.
有时新运算符返回的内存将被初始化,有时它不会取决于您正在新建的类型是POD(普通旧数据),还是它是一个包含POD成员且正在使用的类编译器生成的默认构造函数.
在C++ 1998中,有两种类型的初始化:零和默认
在C++ 2003第三种类型的初始化中,添加了值初始化.
假设:
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编译器中,应该发生以下情况:
new A
- 不确定的价值
new A()
- 零初始化
new B
- 默认构造(B :: m未初始化)
new B()
- 默认构造(B :: m未初始化)
new C
- 默认构造(C :: m为零初始化)
new C()
- 默认构造(C :: m为零初始化)
在符合C++ 03的编译器中,事情应该像这样工作:
new A
- 不确定的价值
new A()
- value-initialize A,这是零初始化,因为它是POD.
new B
- default-initializes(离开B :: m未初始化)
new B()
- value-initializes B,它对所有字段进行零初始化,因为它的默认ctor是编译器生成的而不是用户定义的.
new C
- default-initializes C,调用默认的ctor.
new C()
- value-initializes C,调用默认的ctor.
所以在C++的所有版本中都存在差异new A
,new A()
因为A是POD.
在这种情况下,C++ 98和C++ 03之间的行为有所不同new B()
.
这是C++尘封的角落之一,可以让你发疯.在构造一个物体时,有时候你需要/需要它们,有时候你绝对不能拥有它们,有时它们并不重要.
让我们变得迂腐,因为存在实际上会影响代码行为的差异.以下大部分内容来自对"Old New Thing"文章的评论.
有时新运算符返回的内存将被初始化,有时它不会取决于您正在新建的类型是POD(普通旧数据),还是它是一个包含POD成员且正在使用的类编译器生成的默认构造函数.
在C++ 1998中,有两种类型的初始化:零和默认
在C++ 2003第三种类型的初始化中,添加了值初始化.
假设:
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编译器中,应该发生以下情况:
new A
- 不确定的价值
new A()
- 零初始化
new B
- 默认构造(B :: m未初始化)
new B()
- 默认构造(B :: m未初始化)
new C
- 默认构造(C :: m为零初始化)
new C()
- 默认构造(C :: m为零初始化)
在符合C++ 03的编译器中,事情应该像这样工作:
new A
- 不确定的价值
new A()
- value-initialize A,这是零初始化,因为它是POD.
new B
- default-initializes(离开B :: m未初始化)
new B()
- value-initializes B,它对所有字段进行零初始化,因为它的默认ctor是编译器生成的而不是用户定义的.
new C
- default-initializes C,调用默认的ctor.
new C()
- value-initializes C,调用默认的ctor.
所以在C++的所有版本中都存在差异new A
,new A()
因为A是POD.
在这种情况下,C++ 98和C++ 03之间的行为有所不同new B()
.
这是C++尘封的角落之一,可以让你发疯.在构造一个物体时,有时候你需要/需要它们,有时候你绝对不能拥有它们,有时它们并不重要.
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;
vs 的行为new Thingy();
在C++ 98和C++ 2003之间发生了变化.请参阅Michael Burr关于如何以及为何的解释.
不,他们是一样的.但是有以下区别:
Test t; // create a Test called t
和
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值.
下一个行为取决于您的类型测试.我们有不同的情况:测试有defult构造函数,Test有生成默认构造函数,Test包含POD成员,非POD成员...
假设Test是一个具有已定义构造函数的类,则没有区别.后一种形式使得Test的构造函数运行起来更加清晰,但就是这样.