当前位置:  开发笔记 > 编程语言 > 正文

类型名称后的括号是否与new有区别?

如何解决《类型名称后的括号是否与new有区别?》经验,为你挑选了5个好方法。

如果'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++尘封的角落之一,可以让你发疯.在构造一个物体时,有时候你需要/需要它们,有时候你绝对不能拥有它们,有时它们并不重要.



1> Michael Burr..:

让我们变得迂腐,因为存在实际上会影响代码行为的差异.以下大部分内容来自对"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++尘封的角落之一,可以让你发疯.在构造一个物体时,有时候你需要/需要它们,有时候你绝对不能拥有它们,有时它们并不重要.


现在有人可以添加C++ 11中的情况吗?
@Jon:使用C++ 11,您也可以在堆栈中执行此操作; `B obj {};`将使对象值初始化(为0)而不是`B obj;`将默认初始化(垃圾).
@j_random_hacker,`new A()`将默认初始化C++ 98中的对象,就像使用`new B()`,`new B`,`new C()`和`new C`一样,但是*不是*与`new A`.也就是说,默认初始化总是在C++ 98中完成时:1)该类是非POD并且初始化器缺失,或者2)初始化器是`()`.default-initialization zero初始化对象(如果它是POD),但调用非POD的默认构造函数.
所以tl; dr是`new A`给成员一个不确定的值,而`new A()`将成员值初始化为0 ...除非`A`定义了一个析构函数,在这种情况下两个表达式都给成员一个不确定的值。 ..除非`A`也定义了构造函数,在这种情况下,两个表达式都将成员零初始化...除非它是C ++ 03编译器,在这种情况下,`new A()`会“值初始化”成员,这有什么不同(?)。很简单。
您说“有时候您绝对不能拥有它们(括号)”。在什么情况下您无法添加它们?

2> 小智..:

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关于如何以及为何的解释.



3> 小智..:

不,他们是一样的.但是有以下区别:

Test t;      // create a Test called t

Test t();   // declare a function called t which returns a Test

这是因为基本的C++(和C)规则:如果某些东西可能是一个声明,那么它就是一个声明.

编辑:重新解决有关POD和非POD数据的初始化问题,虽然我同意所有已经说过的内容,但我只想指出这些问题仅适用于新的或以其他方式构建的内容没有用户定义的构造函数.如果有这样的构造函数,它将被使用.对于99.99%的合理设计类,将会有这样的构造函数,因此可以忽略这些问题.


请注意,这是一个特别重要的一点,因为行"Test t(5);" 相当于"测试t =测试(5);" - 但是"测试t();" 与"Test t = Test();"非常不同.+1
-1表示已知的错误答案.您的编辑忽略了由不理解/使用构造函数的前C程序员编写的代码的存在.
-1,我不同意你的说法,即可以忽略这些问题.您不必精确地了解规则,但是如果您必须在没有用户定义的默认构造函数的情况下创建新类,则应该了解它们(然后您应该编写构造函数或查找规则).
但他们不一样.这个答案是完全错误的.它应该被修复或删除,因为它似乎引起了一些混乱,从大量的上票来判断.
那些像struct point {float v [3]; };?对于类似的东西,构造函数是个坏主意,因为它会阻止POD和聚合带来的所有好的属性.所以"问题可以忽略"是错误的,imo.

4> bayda..:

通常,我们在第一种情况下进行默认初始化,在第二种情况下进行值初始化.

例如:在int(POD类型)的情况下:

int* test = new int - 我们有任何初始化和*test的值可以是任何.

int* test = new int() - *test将具有0值.

下一个行为取决于您的类型测试.我们有不同的情况:测试有defult构造函数,Test有生成默认构造函数,Test包含POD成员,非POD成员...



5> Evan Shaw..:

假设Test是一个具有已定义构造函数的类,则没有区别.后一种形式使得Test的构造函数运行起来更加清晰,但就是这样.

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有