4

I just wanted to confirm the difference here, take this as an example:

class Gate
{
   public:
           Gate(); //Constructor
           void some_fun();
   private:
           int one, two;
           ptr p1;
           Gate* next;
};
typedef Gate* ptr;

Gate::Gate()
{
  one = 0;
  two = 0;
}

void Gate::some_fun()
{
  p1 = new Gate;
  p1 = p1->next;
  p1 = new Gate();
}

In my example, I have created 2 new nodes of "Gate" and the only difference between them is that the first node does not have the variables "one and two" initialized, while the second one does.

Josh
  • 3,231
  • 8
  • 37
  • 58
  • 4
    There is no difference between `new T` and `new T()` for a class which has the default constructor explicitly defined like yours. That constructor will be executed in either case. – Pavel Minaev Mar 30 '12 at 18:05
  • @Josh, Did you actually run this code an check the results? – crashmstr Mar 30 '12 at 18:07
  • Your `some_func()` leaks one `Gate` object. – jrok Mar 30 '12 at 18:08
  • @jrok, two actually, since there are no deletes anywhere. But yes, no way to access the first allocated `Gate` in `some_fun`. – crashmstr Mar 30 '12 at 18:10
  • 1
    It is explained at http://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new – xaero99 Mar 30 '12 at 18:17

1 Answers1

11

C++ has two classes of types: PODs and non-PODs (“POD” stands for “plain old data” … a somewhat misleading hint).

For non-PODs, there is no difference between new T and new T(). The difference only affects PODs, for which new T doesn’t initialise the memory, whereas new T() will default-initialise it.

So what are PODs? All built-in C++ types (int, bool …) are.

Furthermore, certain user-defined types are as well. Their exact definition is somewhat complicated but for most purposes it’s enough to say that a POD cannot have a custom constructor (as well as certain other functions) and all its data members must themselves be PODs. For more details, refer to the linked FAQ entry.

Since your class isn’t a POD, both operations are identical.

Community
  • 1
  • 1
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • I am not sure (nor want to actually test, I am feeling lazy here) that POD is the good division in this case: `struct x { int a; std::string b; }`, I *think* for that non-POD type `new x` and `new x()` make a difference. – David Rodríguez - dribeas Mar 30 '12 at 18:17
  • That test does not verify my concern. I was sure that the `std::string` would be initialized, but I was not sure whether the POD member in the struct would be initialized or not. I have written a [test](http://ideone.com/Xg3bW) that verifies that it is uninitialized in either case --the behavior is different than the that of object with automatic duration (functions `f` and `g`) which is what confused me. – David Rodríguez - dribeas Mar 31 '12 at 00:46
  • @David Huh. This test shows that even for `new test()` the POD member of the class is uninitialised and I’m having a really hard time believing that right now. Furthermore, I also don’t understand the results of the stack-allocated object in `x`. Why does it print the filler bytes from your `operator new` after the first call? – Konrad Rudolph Mar 31 '12 at 09:42
  • I will answer the simple one, then think about the other... The simple one is the `new`, the standard determines that `new` for non-POD types (it explicitly says non-POD, which I did not think it did) will call the default constructor, in this case *implicitly defined*. The implicitly defined default constructor is equivalent to `test::test(){}` (no initialization list, no body). Absence of the initialization list means that members with constructors will have it called, but for POD types does nothing. The behavior is expected (knowing that `new T` is *default-initailization*) – David Rodríguez - dribeas Mar 31 '12 at 17:38
  • ... On the other issue (*why is the filler shown in the first pass of the `f()` function?*), the answer is also simple conceptually: because that is the value that is in the stack over which the variable is placed. There are different parts of the code that use that *filling*, the dynamically allocated memory (that cannot be in the stack) but also `operator<<` (and the internal workings of it). I hoped to have a simple example to change the value for something else, but failed. At any rate if you reorder the calls to `f()` and `g()` you will get the last value of the internal variable in `g` – David Rodríguez - dribeas Apr 01 '12 at 14:00
  • @David Well, `operator <<` only contains a single `0xba`. I suspect (but haven’t checked) that the function might be inlined and the loop unrolled, causing `0xbabababa` to be put on the stack. Otherwise I still can’t explain the result. – Konrad Rudolph Apr 01 '12 at 19:04
  • I cannot completely explain the result (I have made a couple of tests without success) but `operator<<` is called with the `x` member that is an `int`, not a single char. There is a single char in `operator new` but that is not the case of `operator<<` – David Rodríguez - dribeas Apr 01 '12 at 20:42
  • @David Yes, I meant `operator new`. – Konrad Rudolph Apr 01 '12 at 23:41