Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do some people define objects as pointers?

Tags:

c++

oop

pointers

I'm currently learning C++ and I can't wrap my head around why one would define an object of a class as a pointer (i.e. Car *c = new Car; as opposed to Car c;) for no apparent reason?

Take for example:

#include <iostream>

class Car {
   public:
   void accelerate() { std::cout << "Accelerating!.\n"; }
};

int main() {
   Car *c = new Car;

   c->accelerate();

   return 0;
}

Why would one do it like that when it is much more intuitive to do it like this:

#include <iostream>

class Car {
   public:
   void accelerate() { std::cout << "Accelerating!.\n"; }
};

int main() {
   Car c;

   c.accelerate();

   return 0;
}

If a pointer to the object is ever needed, one could always declare one, no?

like image 385
Harris Avatar asked Jul 23 '20 11:07

Harris


People also ask

What is meant by pointers to object?

Start Learning. In C++, a pointer holds the address of an object stored in memory. The pointer then simply “points” to the object. The type of the object must correspond with the type of the pointer. type *name; // points to a value of the specified type.

Why do we need pointer objects?

Pointers save memory space. Execution time with pointers is faster because data are manipulated with the address, that is, direct access to memory location. Memory is accessed efficiently with the pointers. The pointer assigns and releases the memory as well.

What type of object is a pointer?

A pointer is a type of variable that carries location information. In this case, the example variable will store the address of an Order object that we want to interact with.

What is the difference between object and pointers?

The pointers pointing to objects are referred to as object pointers. There is a relationship between pointers and objects. Using pointers all the members of the class can be accessed. The following example shows various operations that can be performed on the members of the class through a pointer to objects.


2 Answers

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.
like image 191
Waqar Avatar answered Sep 19 '22 04:09

Waqar


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).

like image 42
Frederik Juul Avatar answered Sep 20 '22 04:09

Frederik Juul