提问者:小点点

类型名称后面的括号与new有区别吗?


如果'test'是一个普通的类,那么以下两个类之间有什么区别吗:

Test* test = new Test;

Test* test = new Test();

共3个答案

匿名用户

让我们来学究一下,因为有一些差异实际上会影响代码的行为。 以下大部分内容摘自对一篇“旧新事物”文章的评论。

有时,new运算符返回的内存将被初始化,有时则不会,这取决于您要更新的类型是一个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编译器中,应发生以下情况:

>

  • 新A-不确定值
  • 新A()-零-初始化

    新建b-默认构造(b::m未初始化)

    新B()-默认构造(B::m未初始化)

    新建C-默认构造(C::m为零-初始化)

    在符合C++03的编译器中,事情应该是这样工作的:

    >

  • 新A-不确定值
  • new A()-value-initialize A,它是零初始化,因为它是一个pod。

    新建b-默认-初始化(保留b::m未初始化)

    new B()-value-initialize B,它零初始化所有字段,因为它的默认ctor是编译器生成的,而不是用户定义的。

    new C-default-初始化调用默认ctor的C。

    所以在所有的C++版本中,new anew a()之间都有区别,因为a是一个pod。

    对于new B(),C++98和C++03之间的行为是不同的。

    这是C++中尘土飞扬,能让你发疯的角落之一。 在构造一个对象时,有时你想要/需要parens,有时你绝对不能拥有它们,有时则无关紧要。

  • 匿名用户

    newthing();是明确表示您希望调用一个构造函数,而newthings;则表示您不介意不调用构造函数。

    如果在具有用户定义构造函数的结构/类上使用,则没有区别。 如果在一个简单的结构/类上调用(例如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();的行为在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%的合理设计的类,都会有这样一个构造器,所以这些问题可以忽略不计。