Quelles sont les différences entre une variable pointeur et une variable référence en C++ ?

Je sais que les références sont un sucre syntaxique, pour que le code soit plus facile à lire et à écrire.

Mais quelles sont les différences ?


Résumé des réponses et des liens ci-dessous :

  1. Un pointeur peut être réaffecté un nombre illimité de fois alors qu'une référence ne peut pas être réaffectée après liaison.
  2. Les pointeurs peuvent pointer nulle part (NULL), alors qu'une référence se réfère toujours à un objet.
  3. Vous ne pouvez pas prendre l&#8217adresse d&#8217une référence comme vous le pouvez avec les pointeurs.
  4. Il n&#8217y a pas d&#8217arithmétique de référence (mais on peut prendre l&#8217adresse d&#8217un objet pointé par une référence et faire de l&#8217arithmétique de pointeur dessus comme dans &obj + 5).

Pour clarifier un malentendu :

La norme C++ est très prudente pour éviter de dicter comment un compilateur peut implémenter les références, mais tous les compilateurs C++ implémentent les références comme des pointeurs. les références comme des pointeurs. C'est-à-dire qu'une déclaration telle que :

int &ri = i ;

si elle n&#8217est pas entièrement optimisée, alloue la même quantité de stockage qu'un pointeur, et place l'adresse de i dans ce stockage.

***Ainsi, un pointeur et une référence utilisent tous deux la même quantité de mémoire.

En règle générale,

  • Utilisez des références dans les paramètres des fonctions et les types de retour pour fournir des interfaces utiles et auto-documentées.
  • Utilisez des pointeurs pour mettre en œuvre des algorithmes et des structures de données.

Lecture intéressante :

  • Mes favoris de tous les temps [C++ FAQ lite][1].
  • Références et pointeurs] [2].
  • Introduction aux références] [3].
  • Références et constantes] [4].

[1] : http://yosefk.com/c++fqa/ref.html [2] : http://www.embedded.com/electronics-blogs/programming-pointers/4023307/References-vs-Pointers [3] : http://www.embedded.com/electronics-blogs/programming-pointers/4024641/An-Introduction-to-References [4] : http://www.embedded.com/electronics-blogs/programming-pointers/4023290/References-and-const

  1. Un pointeur peut être réaffecté :

    int x = 5 ;
    int y = 6 ;
    int *p ;
    p = &x ;
    p = &y ;
    *p = 10 ;
    assert(x == 5) ;
    assert(y == 10) ;

    Une référence ne peut pas, et doit être assignée à l'initialisation :

    int x = 5 ;
    int y = 6 ;
    int &r = x ;
  2. Un pointeur a sa propre adresse mémoire et sa propre taille sur la pile (4 octets sur x86), alors qu'une référence partage la même adresse mémoire (avec la variable originale) mais prend également de l'espace sur la pile. Puisqu'une référence a la même adresse que la variable originale elle-même, il est prudent de considérer une référence comme un autre nom pour la même variable. Remarque : ce vers quoi pointe un pointeur peut se trouver sur la pile ou le tas. Idem pour une référence. Mon affirmation dans cette déclaration n'est pas qu'un pointeur doit pointer vers la pile. Un pointeur est simplement une variable qui contient une adresse mémoire. Cette variable se trouve sur la pile. Puisqu'une référence a son propre espace sur la pile, et puisque l'adresse est la même que la variable qu'elle référence. Plus d'informations sur [stack vs heap][1]. Cela implique qu'il existe une adresse réelle d'une référence que le compilateur ne vous dira pas.

    int x = 0 ;
    int &r = x ;
    int *p = &x ;
    int *p2 = &r ;
    assert(p == p2) ;
  3. Vous pouvez avoir des pointeurs vers des pointeurs vers des pointeurs offrant des niveaux supplémentaires d'indirection. Alors que les références n'offrent qu'un seul niveau d'indirection.

    int x = 0 ;
    int y = 0 ;
    int *p = &x ;
    int *q = &y ;
    int **pp = &p ;
    pp = &q;//*pp = q
    **pp = 4 ;
    assert(y == 4) ;
    assert(x == 0) ;
  4. Le pointeur peut être assigné nullptr directement, alors que la référence ne le peut pas. Si vous essayez assez fort, et que vous savez comment, vous pouvez rendre l'adresse d'une référence nullptr. De même, si vous faites des efforts, vous pouvez avoir une référence à un pointeur, et alors cette référence peut contenir nullptr.

    int *p = nullptr ;
    int &r = nullptr ; 
Commentaires (43)

En dehors du sucre syntaxique, une référence est un pointeur const (non pointeur vers un const). Vous devez établir ce à quoi il se réfère lorsque vous déclarez la variable de référence, et vous ne pouvez pas le changer plus tard.

Mise à jour : maintenant que j'y pense un peu plus, il y a une différence importante.

La cible d'un pointeur const peut être remplacée en prenant son adresse et en utilisant un const cast.

La cible d'une référence ne peut être remplacée par aucun moyen autre que l'UB.

Ceci devrait permettre au compilateur de faire plus d'optimisation sur une référence.

Commentaires (5)

Une référence ne peut jamais être NULL.

Commentaires (10)