If I don't define my own constructor is there any difference between Base *b = new Base;
vs Base *b = new Base();
?
-
Is the first even legal C++ code? – Rafe Kettler Sep 13 '10 at 03:55
-
@Rafe: Yes, the first is perfectly legal. (See the codepad link in my answer) – Billy ONeal Sep 13 '10 at 03:58
-
2The accepted answer is **wrong**. `new T` will *default initialize* the object, while `new T()` will *value initialize* it. – David Rodríguez - dribeas Sep 13 '10 at 08:28
-
1possible duplicate of [Do the parentheses after the type name make a difference with new?](http://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new) – CB Bailey Sep 13 '10 at 08:35
-
Linked question is broader, but accepted answer covers this case too. – MSalters Sep 13 '10 at 09:20
3 Answers
Initialization is kind of a PITA to follow in the standard... Nevertheless, the two already existing answers are incorrect in what they miss, and that makes them affirm that there is no difference.
There is a huge difference between calling new T
and new T()
in classes where there is no user defined constructor. In the first case, the object will be default-initialized, while in the second case it will be `value-initialized*. If the object contains any POD subobject, then the first will leave the POD subobject uninitialized, while the second will set each subelement to 0.
struct test {
int x;
std::string s;
};
int main() {
std::auto_ptr<test> a( new test );
assert( a->s.empty() ); // ok, s is string, has default constructor
// default constructor sets it to empty
// assert( a->x == 0 ); // this cannot be asserted, the value of a->x is
// undefined
std::auto_ptr<test> b( new test() );
assert( b->s.empty() ); // again, the string constructor sets to empty
assert( b->x == 0 ); // this is guaranteed by *value-initialization*
}
For the long road... default-initialize for a user defined class means calling the default constructor. In the case of no user provided default constructor it will call the implicitly defined default constructor, which is equivalent to a constructor with empty initialization list and empty body (test::test() {}
), which in turn will cause the default initialization of each non-POD subobject, and leave all POD subobjects uninitialized. Since std::string
has a user (by some definition of user that includes the standard library writer) provided constructor, it will call such constructor, but it will not perform any real initialization on the x
member.
That is, for a class with user provided default constructor, new T
and new T()
are the same. For a class without such a constructor, it depends on the contents of the class.

- 204,818
- 23
- 294
- 489
-
for non native speakers (including me): (1) http://en.wiktionary.org/wiki/PITA (2) http://stackoverflow.com/questions/146452/what-are-pod-types-in-c – Afriza N. Arief Sep 13 '10 at 08:38
-
+1: now for pointing out the mistake in my response. And +1 for a nice answer. Will queue it for later!!. Made it my favourite question as well – Chubsdad Sep 13 '10 at 08:58
-
@Chubsdad: for what is worth, I did not downvote yours. Also, the question/answer referred as a 'possible duplicate' is better than this one. I am waiting for the question to be closed as exact duplicate to remove this answer anyway. – David Rodríguez - dribeas Sep 13 '10 at 10:20
-
1Paragraph three of this answer is technically incorrect. A constructor with an empty initializer list and an empty constructor body will *not* cause bases and members of POD type to be _default initialized_, it will leave them uninitialized. Only bases and members of non-POD class type are default initialized. If POD bases and members were default initialized then they would be zero initialized and there would have been no difference to value initialization. (12.6.2 [class.base.init] para 4) – CB Bailey Sep 13 '10 at 13:22
-
Assuming `T` is a class, in `new T` default initialization occurs only if `T` is a non-POD. If `T` is a POD, no initialization whatsoever occurs. This is different in C++0x where default initialization always occurs and whether or not the object has an initial value is then determined by default initialization. I can't think of an example where this path of different wording actually has different behavior though. – Johannes Schaub - litb Sep 13 '10 at 16:18
EDIT: SEE @David 's ANSWER -- THIS IS WRONG BUT I CANNOT DELETE IT BECAUSE IT IS ACCEPTED
There is no difference in either case -- it doesn't matter if you define your own constructor or not.
The only difference is that for primitive types (i.e. int
or float
), adding the ()
will initialize the value to zero. (Demonstration on Codepad)
See this example (Output is on codepad)
#include <iostream>
struct ConstructorChecker
{
ConstructorChecker()
{
std::cout << "Hey look! A new constructor checker!" << std::endl;
}
};
struct BasicClass
{
};
int main()
{
//Note constructor called in both cases.
ConstructorChecker *one = new ConstructorChecker;
delete one;
ConstructorChecker *two = new ConstructorChecker();
delete two;
//Same deal -- just because the compiler provides the constructor doesn't mean
//it behaves any differently.
BasicClass *basic = new BasicClass;
delete basic;
BasicClass *basic2 = new BasicClass();
delete basic2;
return 0;
}

- 104,103
- 58
- 317
- 552
-
A subtle and curious difference. The sort of thing about C++ that makes you wonder: _why_? – wilhelmtell Sep 13 '10 at 03:52
-
3@Mike: Backward compatibility doesn't make any sense because `new` has been that way forever. My guess is that they didn't want users to have to pay to initialize the memory to zero, but they wanted to provide a `new` style `calloc` replacement (which requires that the memory be initialized to zero). `()` is a reasonable syntax for that because it looks like you're calling a constructor, which initializes any other kind of value. – Billy ONeal Sep 13 '10 at 04:00
-
I meant "backward compatibility" in the sense of "requiring the `new BasicClass()` syntax and disallowing the `new BasicClass` syntax will break code that uses the latter." That said, I like your explanation better. – Mike DeSimone Sep 13 '10 at 04:14
-
@Mike, since C didn't have `new` or classes there was no need to keep backward compatibility. I believe the two different syntaxes existed from the first C++ spec. – Mark Ransom Sep 13 '10 at 04:36
-
I was referring to backward compatibility to that first C++ spec, not any version of C. As in "C++98 wasn't going to declare `new BasicClass;` illegal." Sorry for the confusion. – Mike DeSimone Sep 13 '10 at 06:16
-
Since you are using *codepaste* to test: http://codepad.org/6YtlUUje. (And note that using a compiler to test is by no means a safe way to tell, the results could well depend on specific compiler behavior) – David Rodríguez - dribeas Sep 13 '10 at 08:21
-
To clarify: the comment " // just because the compiler provides the constructor doesn't mean it behaves any differently." is not proof; it just asserts without source or reference that the answer is yes. – MSalters Sep 13 '10 at 08:24
-
For a detailed explanation, see http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#35 and http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#178. – MSalters Sep 13 '10 at 08:29
-
@David: @Andy: I stand corrected. Unfortunately it won't let me delete the answer because it was given the checkmark :( – Billy ONeal Sep 13 '10 at 13:40
-
@Billy may i recommend that you make your answer community wiki so we can download it without hurting your rep? – Johannes Schaub - litb Sep 13 '10 at 16:09
-
Oops what did I write oO s,download,downvote, Silly litb, I bet that was too late in the evening! – Johannes Schaub - litb Sep 15 '10 at 19:52
As Billy mentioned, both are one and the same.
This is called the 'value initialiation syntax' ($8.5/7).
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

- 24,777
- 4
- 73
- 129
-
1You quote the correct part of the standard, and yet you fail to notice the importance of it... – David Rodríguez - dribeas Sep 13 '10 at 07:54