The main reasons to use pointers in C++ are:
Derived class overrides are called when a method is called on a base class pointer (or reference).
A pointer can be
nullptr. This is a useful sentinel value indicating that an object has no value.
References have no equivalent, while value objects would need to use their field values to indicate that they did not have a real value.
Separating compilation units
The size of pointers is known at compile-time without knowing the size of what they’re pointing to.
This means that classes that contain pointers do not need to be recompiled if the pointed to classes are changed.
This is the Pimpl idiom.
Interface with C library
C objects are generally exposed as pointers to
structs allocated on the heap, so you need to use pointers to manipulate them.
You can wrap the C object in a smart pointer to make this easier and safer.
You need pointers to make data structures like linked lists and binary trees.
To make such a structure it is necessary to be able to associate objects indirectly, which means you can’t use value objects, and also change associations as the data structure is modified, which references don’t allow.
Mostly, you want to pass an object to a function without copying, and pointers and references allow you to do this.
Note that the first and last advantages are shared by references, while the other 4 are specific to pointers.