[c++] C++ Object Instantiation

I'm a C programmer trying to understand C++. Many tutorials demonstrate object instantiation using a snippet such as:

Dog* sparky = new Dog();

which implies that later on you'll do:

delete sparky;

which makes sense. Now, in the case when dynamic memory allocation is unnecessary, is there any reason to use the above instead of

Dog sparky;

and let the destructor be called once sparky goes out of scope?

Thanks!

This question is related to c++ instantiation

The answer is


I had the same problem in Visual Studio. You have to use:

yourClass->classMethod();

rather than:

yourClass.classMethod();


I've seen this anti-pattern from people who don't quite get the & address-of operator. If they need to call a function with a pointer, they'll always allocate on the heap so they get a pointer.

void FeedTheDog(Dog* hungryDog);

Dog* badDog = new Dog;
FeedTheDog(badDog);
delete badDog;

Dog goodDog;
FeedTheDog(&goodDog);

Treat heap as a very important real estate and use it very judiciously. The basic thumb rule is to use stack whenever possible and use heap whenever there is no other way. By allocating the objects on stack you can get many benefits such as:

(1). You need not have to worry about stack unwinding in case of exceptions

(2). You need not worry about memory fragmentation caused by the allocating more space than necessary by your heap manager.


There is an additional reason, which no one else has mentioned, why you might choose to create your object dynamically. Dynamic, heap based objects allow you to make use of polymorphism.


Well, the reason to use the pointer would be exactly the same that the reason to use pointers in C allocated with malloc: if you want your object to live longer than your variable!

It is even highly recommended to NOT use the new operator if you can avoid it. Especially if you use exceptions. In general it is much safer to let the compiler free your objects.


There's no reason to new (on the heap) when you can allocate on the stack (unless for some reason you've got a small stack and want to use the heap.

You might want to consider using a shared_ptr (or one of its variants) from the standard library if you do want to allocate on the heap. That'll handle doing the delete for you once all references to the shared_ptr have gone out of existance.


The only reason I'd worry about is that Dog is now allocated on the stack, rather than the heap. So if Dog is megabytes in size, you may have a problem,

If you do need to go the new/delete route, be wary of exceptions. And because of this you should use auto_ptr or one of the boost smart pointer types to manage the object lifetime.


Treat heap as a very important real estate and use it very judiciously. The basic thumb rule is to use stack whenever possible and use heap whenever there is no other way. By allocating the objects on stack you can get many benefits such as:

(1). You need not have to worry about stack unwinding in case of exceptions

(2). You need not worry about memory fragmentation caused by the allocating more space than necessary by your heap manager.


Well, the reason to use the pointer would be exactly the same that the reason to use pointers in C allocated with malloc: if you want your object to live longer than your variable!

It is even highly recommended to NOT use the new operator if you can avoid it. Especially if you use exceptions. In general it is much safer to let the compiler free your objects.


I've seen this anti-pattern from people who don't quite get the & address-of operator. If they need to call a function with a pointer, they'll always allocate on the heap so they get a pointer.

void FeedTheDog(Dog* hungryDog);

Dog* badDog = new Dog;
FeedTheDog(badDog);
delete badDog;

Dog goodDog;
FeedTheDog(&goodDog);

The only reason I'd worry about is that Dog is now allocated on the stack, rather than the heap. So if Dog is megabytes in size, you may have a problem,

If you do need to go the new/delete route, be wary of exceptions. And because of this you should use auto_ptr or one of the boost smart pointer types to manage the object lifetime.


Though having things on the stack might be an advantage in terms of allocation and automatic freeing, it has some disadvantages.

  1. You might not want to allocate huge objects on the Stack.

  2. Dynamic dispatch! Consider this code:

#include <iostream>

class A {
public:
  virtual void f();
  virtual ~A() {}
};

class B : public A {
public:
  virtual void f();
};

void A::f() {cout << "A";}
void B::f() {cout << "B";}

int main(void) {
  A *a = new B();
  a->f();
  delete a;
  return 0;
}

This will print "B". Now lets see what happens when using Stack:

int main(void) {
  A a = B();
  a.f();
  return 0;
}

This will print "A", which might not be intuitive to those who are familiar with Java or other object oriented languages. The reason is that you don't have a pointer to an instance of B any longer. Instead, an instance of B is created and copied to a variable of type A.

Some things might happen unintuitively, especially when you are new to C++. In C you have your pointers and that's it. You know how to use them and they do ALWAYS the same. In C++ this is not the case. Just imagine what happens, when you use a in this example as an argument for a method - things get more complicated and it DOES make a huge difference if a is of type A or A* or even A& (call-by-reference). Many combinations are possible and they all behave differently.


There's no reason to new (on the heap) when you can allocate on the stack (unless for some reason you've got a small stack and want to use the heap.

You might want to consider using a shared_ptr (or one of its variants) from the standard library if you do want to allocate on the heap. That'll handle doing the delete for you once all references to the shared_ptr have gone out of existance.


I've seen this anti-pattern from people who don't quite get the & address-of operator. If they need to call a function with a pointer, they'll always allocate on the heap so they get a pointer.

void FeedTheDog(Dog* hungryDog);

Dog* badDog = new Dog;
FeedTheDog(badDog);
delete badDog;

Dog goodDog;
FeedTheDog(&goodDog);

Though having things on the stack might be an advantage in terms of allocation and automatic freeing, it has some disadvantages.

  1. You might not want to allocate huge objects on the Stack.

  2. Dynamic dispatch! Consider this code:

#include <iostream>

class A {
public:
  virtual void f();
  virtual ~A() {}
};

class B : public A {
public:
  virtual void f();
};

void A::f() {cout << "A";}
void B::f() {cout << "B";}

int main(void) {
  A *a = new B();
  a->f();
  delete a;
  return 0;
}

This will print "B". Now lets see what happens when using Stack:

int main(void) {
  A a = B();
  a.f();
  return 0;
}

This will print "A", which might not be intuitive to those who are familiar with Java or other object oriented languages. The reason is that you don't have a pointer to an instance of B any longer. Instead, an instance of B is created and copied to a variable of type A.

Some things might happen unintuitively, especially when you are new to C++. In C you have your pointers and that's it. You know how to use them and they do ALWAYS the same. In C++ this is not the case. Just imagine what happens, when you use a in this example as an argument for a method - things get more complicated and it DOES make a huge difference if a is of type A or A* or even A& (call-by-reference). Many combinations are possible and they all behave differently.


Well, the reason to use the pointer would be exactly the same that the reason to use pointers in C allocated with malloc: if you want your object to live longer than your variable!

It is even highly recommended to NOT use the new operator if you can avoid it. Especially if you use exceptions. In general it is much safer to let the compiler free your objects.


I had the same problem in Visual Studio. You have to use:

yourClass->classMethod();

rather than:

yourClass.classMethod();


There is an additional reason, which no one else has mentioned, why you might choose to create your object dynamically. Dynamic, heap based objects allow you to make use of polymorphism.


Treat heap as a very important real estate and use it very judiciously. The basic thumb rule is to use stack whenever possible and use heap whenever there is no other way. By allocating the objects on stack you can get many benefits such as:

(1). You need not have to worry about stack unwinding in case of exceptions

(2). You need not worry about memory fragmentation caused by the allocating more space than necessary by your heap manager.


I've seen this anti-pattern from people who don't quite get the & address-of operator. If they need to call a function with a pointer, they'll always allocate on the heap so they get a pointer.

void FeedTheDog(Dog* hungryDog);

Dog* badDog = new Dog;
FeedTheDog(badDog);
delete badDog;

Dog goodDog;
FeedTheDog(&goodDog);

There's no reason to new (on the heap) when you can allocate on the stack (unless for some reason you've got a small stack and want to use the heap.

You might want to consider using a shared_ptr (or one of its variants) from the standard library if you do want to allocate on the heap. That'll handle doing the delete for you once all references to the shared_ptr have gone out of existance.


Treat heap as a very important real estate and use it very judiciously. The basic thumb rule is to use stack whenever possible and use heap whenever there is no other way. By allocating the objects on stack you can get many benefits such as:

(1). You need not have to worry about stack unwinding in case of exceptions

(2). You need not worry about memory fragmentation caused by the allocating more space than necessary by your heap manager.


The only reason I'd worry about is that Dog is now allocated on the stack, rather than the heap. So if Dog is megabytes in size, you may have a problem,

If you do need to go the new/delete route, be wary of exceptions. And because of this you should use auto_ptr or one of the boost smart pointer types to manage the object lifetime.


Well, the reason to use the pointer would be exactly the same that the reason to use pointers in C allocated with malloc: if you want your object to live longer than your variable!

It is even highly recommended to NOT use the new operator if you can avoid it. Especially if you use exceptions. In general it is much safer to let the compiler free your objects.