Do the parentheses after the type name make a difference with new?

If 'Test' is an ordinary class, is there any difference between:

Test* test = new Test;

and

Test* test = new Test();

Let's get pedantic, because there are differences that can actually affect your code's behavior. Much of the following is taken from comments made to an "Old New Thing" article.

Sometimes the memory returned by the new operator will be initialized, and sometimes it won't depending on whether the type you're newing up is a POD (plain old data), or if it's a class that contains POD members and is using a compiler-generated default constructor.

  • In C++1998 there are 2 types of initialization: zero and default
  • In C++2003 a 3rd type of initialization, value initialization was added.
  • Assume:

    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
    

    In a C++98 compiler, the following should occur:

  • new A - indeterminate value
  • new A() - zero-initialize

  • new B - default construct (B::m is uninitialized)

  • new B() - default construct (B::m is uninitialized)

  • new C - default construct (C::m is zero-initialized)

  • new C() - default construct (C::m is zero-initialized)
  • In a C++03 conformant compiler, things should work like so:

  • new A - indeterminate value
  • new A() - value-initialize A, which is zero-initialization since it's a POD.

  • new B - default-initializes (leaves B::m uninitialized)

  • new B() - value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

  • new C - default-initializes C, which calls the default ctor.

  • new C() - value-initializes C, which calls the default ctor.
  • So in all versions of C++ there's a difference between new A and new A() because A is a POD.

    And there's a difference in behavior between C++98 and C++03 for the case new B() .

    This is one of the dusty corners of C++ that can drive you crazy. When constructing an object, sometimes you want/need the parens, sometimes you absolutely cannot have them, and sometimes it doesn't matter.


    new Thing(); is explicit that you want a constructor called whereas new Thing; is taken to imply you don't mind if the constructor isn't called.

    If used on a struct/class with a user-defined constructor, there is no difference. If called on a trivial struct/class (eg struct Thing { int i; }; ) then new Thing; is like malloc(sizeof(Thing)); whereas new Thing(); is like calloc(sizeof(Thing)); - it gets zero initialized.

    The gotcha lies in-between:

    struct Thingy {
      ~Thingy(); // No-longer a trivial class
      virtual WaxOn();
      int i;
    };
    

    The behavior of new Thingy; vs new Thingy(); in this case changed between C++98 and C++2003. See Michael Burr's explanation for how and why.


    No, they are the same. But there is a difference between:

    Test t;      // create a Test called t
    

    and

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

    This is because of the basic C++ (and C) rule: If something can possibly be a declaration, then it is a declaration.

    Edit: Re the initialisation issues regarding POD and non-POD data, while I agree with everything that has been said, I would just like to point out that these issues only apply if the thing being new'd or otherwise constructed does not have a user-defined constructor. If there is such a constructor it will be used. For 99.99% of sensibly designed classes there will be such a constructor, and so the issues can be ignored.

    链接地址: http://www.djcxy.com/p/6930.html

    上一篇: JSON.stringify和JSON.parse之间的区别

    下一篇: 类型名称后面的括号与新的有什么不同?