patterncppCritical
Do the parentheses after the type name make a difference with new?
Viewed 0 times
withnamenewthedifferenceparenthesesaftertypemake
Problem
If
and:
Test is an ordinary class, is there any difference between:Test* test = new Test;
and:
Test* test = new Test();
Solution
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.
Assume:
In a C++98 compiler, the following should occur:
-
-
-
-
-
-
In a C++03 conformant compiler, things should work like so:
-
-
-
-
-
-
So in all versions of C++ there's a difference between
And there's a difference in behavior between C++98 and C++03 for the case
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.
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 mIn 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.
Code Snippets
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 mContext
Stack Overflow Q#620137, score: 1043
Revisions (0)
No revisions yet.