Permettez-moi d'essayer de répondre à cela aussi.
Les pointeurs sont similaires aux références. En d'autres termes, ce ne sont pas des copies, mais plutôt un moyen de se référer à la valeur d'origine.
Avant toute chose, un endroit où vous devrez généralement beaucoup utiliser des pointeurs est lorsque vous avez affaire à du matériel embarqué . Vous devez peut-être basculer l'état d'une broche d'E / S numérique. Vous traitez peut-être une interruption et devez stocker une valeur à un emplacement spécifique. Vous obtenez l'image. Cependant, si vous ne traitez pas directement avec du matériel et que vous vous demandez simplement quels types utiliser, lisez la suite.
Pourquoi utiliser des pointeurs par opposition aux variables normales? La réponse devient plus claire lorsque vous traitez avec des types complexes, comme les classes, les structures et les tableaux. Si vous deviez utiliser une variable normale, vous pourriez finir par faire une copie (les compilateurs sont assez intelligents pour empêcher cela dans certaines situations et C ++ 11 aide aussi, mais nous resterons à l'écart de cette discussion pour l'instant).
Maintenant, que se passe-t-il si vous souhaitez modifier la valeur d'origine? Vous pouvez utiliser quelque chose comme ceci:
MyType a; //let's ignore what MyType actually is right now.
a = modify(a);
Cela fonctionnera très bien et si vous ne savez pas exactement pourquoi vous utilisez des pointeurs, vous ne devriez pas les utiliser. Méfiez-vous de la raison "ils sont probablement plus rapides". Exécutez vos propres tests et s'ils sont réellement plus rapides, utilisez-les.
Cependant, supposons que vous résolviez un problème où vous devez allouer de la mémoire. Lorsque vous allouez de la mémoire, vous devez la désallouer. L'allocation de mémoire peut réussir ou non. C'est là que les pointeurs sont utiles - ils vous permettent de tester l'existence de l'objet que vous avez alloué et ils vous permettent d'accéder à l'objet pour lequel la mémoire a été allouée en dé-référençant le pointeur.
MyType *p = NULL; //empty pointer
if(p)
{
//we never reach here, because the pointer points to nothing
}
//now, let's allocate some memory
p = new MyType[50000];
if(p) //if the memory was allocated, this test will pass
{
//we can do something with our allocated array
for(size_t i=0; i!=50000; i++)
{
MyType &v = *(p+i); //get a reference to the ith object
//do something with it
//...
}
delete[] p; //we're done. de-allocate the memory
}
C'est la raison pour laquelle vous utiliseriez des pointeurs - les références supposent que l'élément auquel vous faites référence existe déjà . Un pointeur ne fonctionne pas.
L'autre raison pour laquelle vous utiliseriez des pointeurs (ou au moins finissez par les gérer) est qu'ils sont un type de données qui existait avant les références. Par conséquent, si vous finissez par utiliser des bibliothèques pour faire les choses que vous savez être meilleures, vous constaterez que beaucoup de ces bibliothèques utilisent des pointeurs partout, simplement en raison de la durée de leur existence (beaucoup d'entre eux ont été écrits avant C ++).
Si vous n'avez utilisé aucune bibliothèque, vous pouvez concevoir votre code de manière à vous tenir à l'écart des pointeurs, mais étant donné que les pointeurs sont l'un des types de base du langage, plus vous vous familiarisez rapidement avec leur utilisation, plus portable vos compétences C ++ seraient.
Du point de vue de la maintenabilité, je dois également mentionner que lorsque vous utilisez des pointeurs, vous devez soit tester leur validité et gérer le cas quand ils ne sont pas valides, soit supposer qu'ils sont valides et accepter le fait que votre programme va planter ou pire QUAND cette hypothèse est brisée. Autrement dit, votre choix avec des pointeurs est soit d'introduire une complexité de code, soit de faire plus d'efforts de maintenance en cas de rupture et que vous essayez de retrouver un bogue qui appartient à toute une classe d'erreurs que les pointeurs introduisent, comme la corruption de mémoire.
Donc, si vous contrôlez tout votre code, éloignez-vous des pointeurs et utilisez plutôt des références, en les conservant constantes quand vous le pouvez. Cela vous obligera à réfléchir à la durée de vie de vos objets et finira par garder votre code plus facile à comprendre.
N'oubliez pas cette différence: une référence est essentiellement un pointeur valide. Un pointeur n'est pas toujours valide.
Alors, je dis qu'il est impossible de créer une référence invalide? Non, c'est tout à fait possible, car C ++ vous permet de faire presque n'importe quoi. C'est juste plus difficile à faire involontairement et vous serez étonné de voir combien de bugs sont involontaires :)