Raison de passer un pointeur par référence en C ++?

Dans quelles circonstances voudriez-vous utiliser du code de cette nature en c ++?

void foo(type *&in) {...} void fii() { type *choochoo; ... foo(choochoo); } 

Vous souhaitez passer un pointeur par référence si vous avez besoin de modifier le pointeur plutôt que l’object sur lequel pointe le pointeur.

Ceci est similaire à pourquoi les doubles pointeurs sont utilisés; utiliser une référence à un pointeur est légèrement plus sûr que d’utiliser des pointeurs.

50% des programmeurs C ++ aiment définir leurs pointeurs sur null après une suppression:

 template void moronic_delete(T*& p) { delete p; p = nullptr; } 

Sans la référence, vous ne modifiez qu’une copie locale du pointeur, sans affecter l’appelant.

La réponse de David est correcte, mais si c’est encore un petit résumé, voici deux exemples:

  1. Vous pourriez vouloir mettre à zéro tous les pointeurs libérés pour détecter les problèmes de mémoire plus tôt. C-style que vous feriez:

     void freeAndZero(void** ptr) { free(*ptr); *ptr = 0; } void* ptr = malloc(...); ... freeAndZero(&ptr); 

    En C ++ pour faire la même chose, vous pourriez faire:

     template void freeAndZero(T* &ptr) { delete ptr; ptr = 0; } int* ptr = new int; ... freeAndZero(ptr); 
  2. Lorsque vous traitez des listes liées – souvent simplement représentées comme des pointeurs vers un nœud suivant:

     struct Node { value_t value; Node* next; }; 

    Dans ce cas, lorsque vous insérez dans la liste vide, vous devez nécessairement modifier le pointeur entrant car le résultat n’est plus le pointeur NULL . C’est un cas où vous modifiez un pointeur externe à partir d’une fonction, de sorte qu’il aurait une référence au pointeur dans sa signature:

     void insert(Node* &list) { ... if(!list) list = new Node(...); ... } 

Il y a un exemple dans cette question .

J’ai dû utiliser un code comme celui-ci pour fournir des fonctions permettant d’allouer de la mémoire à un pointeur transmis et renvoyer sa taille car ma société “m’objecte” à l’aide de la STL

  int iSizeOfArray(int* &piArray) { piArray = new int[iNumberOfElements]; ... return iNumberOfElements; } 

Ce n’est pas bien, mais le pointeur doit être passé par référence (ou utiliser un double pointeur). Si ce n’est pas le cas, la mémoire est affectée à une copie locale du pointeur si elle est transmise par valeur, ce qui entraîne une fuite de mémoire.

Par exemple, lorsque vous écrivez une fonction d’parsing et que vous lui transmettez un pointeur source, si la fonction est supposée pousser ce pointeur vers l’avant du dernier caractère correctement reconnu par l’parsingur. L’utilisation d’une référence à un pointeur indique clairement que la fonction déplacera le pointeur d’origine pour mettre à jour sa position.

En général, vous utilisez des références à des pointeurs si vous souhaitez passer un pointeur sur une fonction et le laisser déplacer le pointeur d’ origine vers une autre position au lieu de simplement déplacer une copie sans affecter l’original.

Une autre situation où vous pourriez avoir besoin de ceci est si vous avez une collection stl de pointeurs et que vous voulez les changer en utilisant l’algorithme stl. Exemple de for_each dans c ++ 98.

 struct Storage { typedef std::list ObjectList; ObjectList objects; void change() { typedef void (*ChangeFunctionType)(Object*&); std::for_each (objects.begin(), objects.end(), &Storage::changeObject); } static void changeObject(Object*& item) { delete item; item = 0; if (someCondition) item = new Object(); } }; 

Sinon, si vous utilisez la signature changeObject (Object * item), vous avez une copie du pointeur, pas un original.