I've just read a tutorial on Classes Under the hood/behind the scenes.
It says that:

Foo* A = new Foo();

// Is different from:

Foo* B = new Foo;

What in the world? I never put the brackets for my classes like that. Why does the first initialize variables and the second not do the same?

Does this only happen if I use the new operator? Example:

Foo A();

Foo B;

Does it happen for these too? Or is it just the new operator alone?

This tutorial completely threw me off and caught me off guard as now I'm thinking that none of my classes were initialized even though in my constructor I do:

Foo() : VarX(0), VarY(0)
Foo(int X, int Y) : VarX(X), VarY(Y)

Please clear up these details for me.

Edited 4 Years Ago by triumphost

Don't panic, relax, all is well.

What that tutorial is refering to is the difference between value-initialization, default-initialization, and zero-initialization. These are a set of rules that the compiler follows to initialize objects in different "construction from nothing" cases.

Basically, value-initialization and zero-initialization are the same, they set everything to zero (unless there is a user-defined default constructor for that class). This will occur when you write:

Foo f = Foo();   // value-initialized local variable.
     // btw: Foo f();  is an error, it is a function declaration!

Foo* pf = new Foo();  // value-initialized dynamically-allocated object.

Bar() : member_var() { };  // value-initialized data member.

While default-initialization will call the default constructor of the class if one exists (user-defined or not), otherwise it doesn't do any initialization. This will occur when you write:

Foo f;   // default-initialized local variable.

Foo* pf = new Foo;  // default-initialized dynamically-allocated object.

Bar() { };  // member_var will be default-initialized.

The same initialization rules apply to all kinds of initialization, whether it is a local (static) variable, a dynamically-allocated one, or a class data member (or a base-class initialization). There are only some special rules for global variable (with externs and stuff), but you don't have to worry about that.

At the end of the day, class types always use the default constructor (user-defined or not). The only "weird" thing about this is that primitive types (int, float, etc.) can be initialized to zero without having to do int i = 0;, new int(0) or Bar() : int_member(0) { };, but just by doing int i = int();, new int() or Bar() : int_member() { };. Personally, I don't see much point in omitting the 0, it's just confusing. And, of course, primitive types (including pointers) that do not have an initializer will not be initialized at all, but that's just basic C++ knowledge, i.e., uninitialized variables are uninitialized!

You should read section 8.5 of the C++ standard for a complete explanation of initializers, it really clears things up.

Comments
Thank you! I feel much safer now. Going to read the PDF. :)

Hey I have a question. Why is Foo X() wrong? I do that all the time and it uses my classes :S I read that on cplusplus when I started learning classes.

The compiler gives no error even with all options turned on.
Why do I need the equal sign to declare a class like you did?

Edited 4 Years Ago by triumphost

Why is Foo X(); wrong?

Because that is the declaration of a function that is called X, returns an object of type Foo, and takes no parameters. Because function prototypes can appear anywhere, including all places where variables can be declared, there is an ambiguity (is it a function? is it a variable?). The C++ standard resolves the issue by saying that if an ambiguity exists, then it should be interpreted as a function declaration. So, Foo X(); is a function declaration.

Why do I need the equal sign to declare a class like you did?

The equal-sign declaration just resolves the ambiguity in this case.

The compiler gives no error even with all options turned on.

That is a bit surprising, but I would guess your compiler bends the standard a bit on this issue (all compilers deviate from the standard a bit, especially with things that the compiler can accept, that wouldn't normally be accepted).

This question has already been answered. Start a new discussion instead.