6

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

Hello all,

class Car
{
public:
    Car() : m_iPrice(0) {}
    Car(int iPrice) : m_iPrice(iPrice) {}

private:
    int m_iPrice;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Car  car1;    // Line 1
    Car  car2();  // Line 2, this statement declares a function instead.

    Car* pCar = new Car; // Line 3
    Car* pCar2 = new Car(); // Line 4

    return 0;
}

Here is my question:

When we define an object of Car, we should use Line 1 rather than Line 2. When we new an object, both Line 3 and Line 4 can pass the compiler of VC8.0. However, what is the better way Line 3 or Line 4? Or, Line 3 is equal to Line 4.

Thank you

Community
  • 1
  • 1
q0987
  • 34,938
  • 69
  • 242
  • 387
  • 2
    [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) – wkl Dec 30 '10 at 16:26
  • @birryree: In general yes (the difference is Value-initialization Vs Zero-initialization). In this specific instance no; because Car is very simple class (with only an int member) with an explicitly defined default constructor. – Martin York Dec 30 '10 at 20:24
  • @Martin - are you answering the question? It's the title of the question I'm linking to. :) – wkl Dec 30 '10 at 20:34
  • @birryree: I am answering you question in the comment above. – Martin York Dec 30 '10 at 20:43

3 Answers3

7

In this case the lines are equivalent; there's no difference in operation.

However, please be careful - this does not mean that such lines are ALWAYS equialent. If your data type is a POD (i.e. a simple struct:

struct Foo
{
    int a;
    float b;
};

Then new Foo produces a uninitialized object, and new Foo() calls a value initalization constructor, which value-initializes all fields - i.e. sets them to 0 in this case.

Since in such cases it's easy to accidentally call new Foo(), forget to initialize objects (this is fine!), and then accidentally make your class non-POD (in which case the value-initialization will not be done and the object will be uninitialized again), it's slightly better to always call new Foo (though this produces a warning in some MSVC versions).

zeuxcg
  • 9,216
  • 1
  • 26
  • 33
2

It makes no difference when the type you new has a user declared constructor.

If it doesn't, then Line 4 will initialize all the members to zero first (but only call constructors for those members that have user declared constructors) and do the same to base classes. If you don't want to have that done, use Line 3. This rule also takes place for complex objects with virtual member functions, base classes and so on - only condition is whether or not the class has a user declared constructor.

This is a very subtle corner of C++, and I think I wouldn't base my code on these facts without having a comment explaining that in the code (oh dear, my colleagues will get mad at me otherwise).

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • It's not just the default constructor of the newed class but all member and base clases can be affected. – Martin York Dec 30 '10 at 20:27
  • @Martin if a member has a user declared constructor, the default constructor is tried to be called. No member is touched then. If there is no user declared constructor, members and bases are initialized. I missed "bases" - will add it right away. – Johannes Schaub - litb Dec 30 '10 at 20:37
0

This has been discussed earlier also C++ Classes default constructor and Is this' type variableofType()' function or object?

Community
  • 1
  • 1
Neera
  • 1,577
  • 8
  • 10