2
class A
{
public:
    int get(void){return stuff;}
    void set(int s){stuff = s;}

private:
    int stuff;
};

int _tmain(int argc, _TCHAR* argv[])
{
    A a;
    A b();
    A* ap = new A;
    A* bp = new A();
}

I don't know what the difference is between the four lines in main() exactly and which situations I might use one versus the other (other than being on the stack or heap). I noticed that the fourth line actually initializes "stuff" to 0, whereas the other lines do not. The second line doesn't seem to be anything at all, which seems odd.

Question: What is each line's tradeoffs/meanings (in main())? Whether to use parens or not is confusing to me.

Todd
  • 305
  • 2
  • 9
  • 2
    Don't use `new`. `b` is not an object. By elimination, the only remaining option is `a`. – Kerrek SB Nov 01 '13 at 17:02
  • 6
    For starters, `A b();` doesn't construct an object. Its a [function declaration](http://en.wikipedia.org/wiki/Most_vexing_parse). – WhozCraig Nov 01 '13 at 17:03
  • Partly relevant http://stackoverflow.com/q/620137/1171191 – BoBTFish Nov 01 '13 at 17:05
  • `a` is a local variable and it will be "freed" when it goes out of scope (at the end of the code block), `bp` object will still exist when its pointer goes out of scope unless you explicitly delete it. – SJuan76 Nov 01 '13 at 17:06

2 Answers2

9
A a;

That's default-initialisation. Since there's no default constructor, each data member is default-initialised; so a.stuff is left with an indeterminate value.

A b();

That declares a function. It doesn't create an object.

A* ap = new A;

That dynamically allocates an object, and default-initialises it as described above. Since you never delete it, the memory is leaked. You shouldn't use new unless you really need a dynamic lifetime; and when you do, you should usually use smart pointers to delete it at the right time, avoiding leaks.

A* bp = new A();

That dynamically allocates an object and value-initialises it. Since there's no default constructor, it value-initialises each data member; so bp->stuff is initialised to zero. Again, the memory is leaked.

If the class had a default constructor, then default- and value-initialisation would be identical; both would call the constructor.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
2
int _tmain(int argc, _TCHAR* argv[])
{
    A a; // creates a local automatic variable of type A
    A b(); // See Most Vexing Parse
    A* ap = new A; // creates a new object of type A on the heap using the default constructor (which the compiler implements for you since you didn't declare one)
    A* bp = new A(); // creates a new object of type A on the heap using value initialization (effectively the same as above).
}

Most Vexing Parse

In general, you will use A a; the vast majority of the time. A b(); does not declare an instance of an object. The dynamic memory versions (which would also require corresponding deletes), should only be used if rare cases, and should be wrapped in smart pointer templates (e.g. std::unique_ptr, std::shared_ptr) or as part of std containers (e.g. std::vector, std::list). It is very rare that you will have to create something on the heap and manage it yourself.

Zac Howland
  • 15,777
  • 1
  • 26
  • 42