Why do some people define objects as pointers?

why one would define an object of a class as a pointer

One shouldn't. Pointers are generally to be avoided as much as possible. However, they are necessary when you are doing polymorphism. In that case, use the smart pointers shared_ptr, unique_ptr instead of a raw pointer.

The following is a bad example of using pointers because now you have one additional problem i.e., "freeing the allocated memory".

int main() {
   Car *c = new Car;
   c->accelerate();
   return 0;
}

And you are right, the second example is much better and should be the default way to go.

Whenever such questions occur, it is best to see what C++ Core Guidelines say:

R.11: Avoid calling new and delete explicitly

Reason

The pointer returned by new should belong to a resource handle (that can call delete). If the pointer returned by new is assigned to a plain/naked pointer, the object can be leaked.

ES.60: Avoid new and delete outside resource management functions

Reason

Direct resource management in application code is error-prone and tedious.

R.3: A raw pointer (a T*) is non-owning

Reason

There is nothing (in the C++ standard or in most code) to say otherwise and most raw pointers are non-owning. We want owning pointers identified so that we can reliably and efficiently delete the objects pointed to by owning pointers. (Owning pointers are pointers which take ownership of a pointer and are responsible for freeing it.)

Example

void f()
{
   int* p1 = new int{7};           // bad: raw owning pointer
   auto p2 = make_unique<int>(7);  // OK: the int is owned by a unique pointer
   // ...
}

So, the answer is use pointers only when you absolutely need to, otherwise stick to references and values.

When to use pointers?

  • When you are doing polymorphism (use smart pointers)
  • When you are need a huge array (> 1MB) because stack size is limited. (2 - 8 MB(usually) on linux, 1 MB on windows). Prefer using std::vector in this case if you can.
  • Pointers can sometimes be necessary when you are using "C" libraries or dealing with legacy C++ code.

The critical difference between your two examples is memory allocation and lifetimes.

Anything allocated by using new is allocated on the heap and must be de-allocated by calling delete. In your first example, you have created a memory leak, as the Car is never de-allocated. In modern C++ you should largely not use new or delete but instead use smart pointers (something like auto c = std::make_unique<Car>();)

The reason why you would want do this, would be to generate something which outlives the scope of the function.

In your second example the Car is created on the stack and is de-allocated when it goes out of scope (when the function returns).

Tags:

C++

Oop

Pointers