views:

214

answers:

2
Class A 
{
};

What is the difference between A a , A* a and A* a = new A().

+8  A: 

A a declares an instance of A named a

A *a declares a pointer to a A class

A *a = new A() allocates space for a on the heap and calls the proper constructor (if no constructor is specified, it performs default initialization).

For further information about the last form see http://en.wikipedia.org/wiki/New_%28C%2B%2B%29

klez
Although the last one should have been `A* a = ...`
Andreas Brinck
Indeed. I'll correct my answer
klez
The last one doesn't just allocate space for `a` on the heap. It also initializes the `A` object, and declares a pointer to it.
jalf
@Jalf, how about A a, where does it allcate memory . i can see constructor gets implicitly called when we put A a .
Sachin Chourasiya
@Sachin: wherever it is declared. If a class contains a member declared in this way, it increases the class object's size enough to hold an additional `A`. If it is declared in a function, it is put on the call stack.
jalf
@jalf, Does it mean unless I use new the memory gets allocated on stack rather than on heap.
Sachin Chourasiya
@Sachin: Yep, exactly
jalf
@jalf: thanks, corrected
klez
Same error as in the other answer. `A()` calls the contructor only when it is explicitly declared by user. Otherwise, it perform *value-initialization*, which does not involve the constructor of `A`.
AndreyT
@AndreyT, corrected
klez
+15  A: 
A a;

Creates an instance of an A that lives on the stack using the default constructor.

A *a;

Is simply a uninitialized pointer to an A. It doesn't actually point to an A object at this point, but could. An initialized pointer (in this case, set to NULL) would look like so:

A *a = 0;

The difference here is that a null pointer does not point to any object while an uninitialized pointer might point anywhere. Initializing your pointers is a good practice to get into lest you find yourself wondering why your program is blowing up or yielding incorrect results.

Similarly, you don't want to attempt to dereference either a NULL pointer or an uninitialized pointer. But you can test the NULL pointer. Testing an uninitialized pointer yields undetermined and erroneous results. It may in fact be != 0 but certainly doesn't point anywhere you intend it to point. Make sure you initialize your pointers before testing them and test them before you attempt to dereference them.

A a = new A();

should be written as

A *a = new A();

and that creates a new A object that was allocated on the heap. The A object was created using the default constructor.

Where a default constructor is not explicitly written for a class, the compiler will implicitly create one though I don't believe the standard does not specify the state of data members for the object implicitly instantiated. For a discussion about implicit default constructors, see Martin York's response to this SO question.

itsmatt
It's probably worth noting that `A a` calls the default constructor too, if you're going to mention that about the heap-allocated version.
Tyler McHenry
@Tyler - thanks, modified it to mention that.
itsmatt
Its also worth noting that `A *a;` creates an uninitialized pointer. The only thing that you can do with it is assign a value to it (meaning, no comparisons or other uses). It might be worth adding a fourth example, `A *a = 0`, in which case `a` can be used in comparisons.
KeithB
@KeithB - thanks, added a note about that. Good point.
itsmatt
The last statement is incorect. The object `A()` is created with *value-initialization*. It doesn't use any contructors of `A` (in this case). Expression `A()` will use the default contructor only when it is explicitly declared by user. Otherwise, the initialization proceeds without using the constructor.
AndreyT
@AndreyT - Agreed - there will be an implicit construction done by the compiler if there isn't a default constructor explicitly defined for the class. The assumption I made here was that there was one - despite the fact that OP's class is empty - because there typically is one defined. The distinction is a good one to make and I thank you for pointing that out. I'll add a note to the answer.
itsmatt
Consider: `struct A { ~A() { } int const a; };`. Then `new A()` is perfectly valid (and initializes `a` to zero). But if it would use the default constructor like in `A a;` or `new A` it would be ill-formed (because of the `const` member). So it makes a big difference whether the default constructor is used or not.
Johannes Schaub - litb