Un ejemplo simple: Para trabajar con memoria dinámica, trabajas con punteros, pues es lo que necesitas: un puntero a un bloque de memoria.
Luego, en C++, hay constructores, constructores de copia, constructores de movimiento y destructores. Estas funciones no las llamas tú; se llaman solas en el momento adecuado. Utilizando punteros, evitas llamar, por ejemplo, constructores de copia. Además, como el puntero puede no apuntar a un objeto, tienes la posibilidad de construir el objeto en el momento justo en el que lo necesites.
Imaginate un array de 5 elementos:
Obj *array = new Obj[5];
Esos 5 elementos han sido construidos. Imagina ahora que quieres incrementar a 6 el tamaño. Tienes que mover o copiar uno a uno los elementos. Mover es algo relativamente rápido. Pero copiar puede ser muy pesado, y no todas las clases se pueden mover. Una opción aquí, es guardar un array de punteros:
Obj **array = new Obj*[5];
for(int i=0; i<5; i++){
array[i] = new Obj();
}
Así, cuando se crea el nuevo array de 6 elementos, solo vas a tener que copiar los punteros (que no son más que números), y evitas copiar todos los objetos. La diferencia de rendimiento es muy grande.
En cualquier caso, no te preocupes. ya encontrarás el momento para usarlos cuando los necesites.
Así como detalle, una lista enlazada, ¿cómo la harías?