Les références en C++ - déclaration et interêts

19 Mar 2022 19 Mar 2022 3249 vues ESSADDOUKI Mostafa 9 min de lecture
Introduction et syntaxe de base
1 Introduction au langage C++ 2 Entrée-sortie en C++ - cin et cout 3 Inférence de type avec le mot-clé auto en C++ 4 Classe std::string et les chaînes de caractères en C++ 5 Les structures conditionnelles (if et switch) en C++ (C++17 et C++20) 6 Les boucles en C++ (C++17 et C++20) 7 La gestion des fichiers en C++
Pointeurs et fonctions
8 Introduction aux pointeurs en C++ - Déclaration et interêts 9 Les références en C++ - déclaration et interêts 10 Les tableaux en C++ - Déclaration et interêts 11 Introduction aux fonctions en C++ 12 Passer des arguments à une fonction en C++ 13 Déclarer un paramètre const en C++ 14 Les fonctions Lambda en C++ 15 Fonctions utiles (Mathématiques et caractères) en C++
Programmation OO
16 Classes et objets en C++ 17 Spécificateurs d'accès en C++ 18 Constructeurs et destructeur d'une classe en C++ 19 Fonctions membres en C++ 20 Membres statiques d'une classe en C++ 21 Fonctions en ligne en C++ - inline 22 Fonctions et classes amies en C++ - friend 23 Surcharge des fonctions en C++ 24 Surcharge des opérateurs en C++ 25 Héritage en C++ 26 La gestion d'exceptions en C++ : déclaration, utilisation et personnalisation 27 fonctions et classes templates en C++ 28 Les nouveautés C++20 pour améliorer les templates en C++
Structures de données
29 Introduction aux structures de données 30 Les structures en C++ et la différence avec les structures en C 31 Les listes chaînées en C++ 32 Les piles en C++ 33 File d'attente en C++ 34 Arbre binaire de recherche : définition et mise en oeuvre en C++
La bibliothèque standard (STL)
35 Introduction à la bibliothèque de Template Standard STL 36 Les itérateurs en C++ - définition, déclaration et exemples 37 La classe array en C++ (bibliothèque STL) <array> 38 La classe vector de la bibliothèque STL <vector> 39 La classe deque en C++ ( Bibliothèque STL) 40 La classe list en C++ (bibliothèque STL) <list> 41 La classe stack (Pile) en C++ (bibliothèque STL) <stack> 42 La classe queue (File d'attente) en C++ (bibliothèque STL) <queue> 43 La file d'attente prioritaire (classe priority_queue) - Bibliothèque STL 44 Les ensembles en C++ (Classe set <set> - Bibliothèque STL) 45 Les dictionnaires en C++ : Classe map (Bibliothèque STL) 46 Introduction aux algorithmes de la bibliothèque STL (programmation compétitive) 47 Tri et méthodes associées en C++ - Bibliothèque STL 48 Recherche dichotomique et méthodes associées en C++ - Bibliothèque STL 49 Appliquer un prédicat ou une fonction aux éléments d'une séquence en C++ - Bibliothèque STL 50 Recherche dans une séquence et méthodes associées en C++ - Bibliothèque STL

Les références en C++

Définition

Une référence est un nom que vous pouvez utiliser comme alias pour une autre variable. Elle est similaire à un pointeur, mais avec des différences cruciales.

Les références deviennent particulièrement importantes dans le contexte de la programmation orientée objet et des fonctions.

À retenir

Contrairement à un pointeur, une référence :

  • Doit être initialisée dès sa déclaration
  • Ne peut pas être réaffectée à une autre variable
  • Est un alias, pas une variable avec sa propre adresse

Création de références

Une référence est déclarée de la même manière qu'une variable normale, sauf qu'une esperluette (&) est ajoutée entre le type de données et le nom de la variable.

Exemple 1 : Déclaration de références

   
Déclaration et initialisation C++
int x {5};
int& r {x};    // r est un alias de x
int &s {x};    // syntaxe alternative (espace avant &)
int& t;        // ERREUR : doit être initialisée !

Explication :

  • int& r {x}; : r est une référence à un entier, initialisée avec x.
  • r devient un alias pour x : toute modification de r affecte x, et vice-versa.
  • Une référence doit être initialisée immédiatement (contrairement aux pointeurs).

Exemple 2 : Utilisation d'une référence

int x {5};
int& r {x};

r = 10;  // modifie x via la référence
cout << x;  // affiche 10
cout << r;  // affiche aussi 10
Sortie
10
10

Références et pointeurs

Comparaison

Une référence est similaire à un pointeur qui pointe toujours vers la même chose. Cependant :

  • Un pointeur est une variable qui pointe vers une autre variable.
  • Une référence n'est qu'un alias et n'a pas d'adresse propre.

Exemple 3 : Adresse d'une référence

int x {5};
int& r {x};

int* ptr = &r;  // l'adresse assignée à ptr est l'adresse de x
// &r et &x donnent la même adresse !

Prendre l'adresse d'une référence donne l'adresse de la variable référencée. La référence elle-même n'a pas d'adresse propre.

Comparaison détaillée

CaractéristiquePointeurRéférence
InitialisationPeut être déclaré sans initialisation (pointeur nul)Doit être initialisé immédiatement
RéaffectationPeut pointer vers différentes variablesNe peut pas être réaffecté (reste lié à la même variable)
Valeur nullePeut être nullptrNe peut pas être nul (doit toujours référencer quelque chose)
DéréférencementNécessite * pour accéder à la valeurUtilisation directe (comme une variable normale)
Adresse propreOui (on peut prendre l'adresse du pointeur)Non (l'adresse de la référence est celle de la variable)
Recommandation

Généralement, chaque fois qu'un pointeur n'a pas besoin d'être réaffecté, une référence doit être utilisée à la place, car une référence est plus sûre : elle doit toujours faire référence à quelque chose, donc pas besoin de vérifier si elle est nulle.

Exemple 4 : Piège avec les références

Attention : Référence invalide

Il est possible qu'une référence soit invalide - par exemple, lorsqu'une référence fait référence à un pointeur nul.

int* ptr = nullptr;  // pointeur nul
int& ref = *ptr;     // DANGER : ref est une référence à une zone mémoire invalide
ref = 10;            // ERREUR : accès mémoire invalide

Ce type d'erreur est plus facile à éviter avec des références qu'avec des pointeurs, car on ne peut pas déclarer une référence non initialisée. Cependant, il faut rester vigilant avec les déréférencements de pointeurs.

Références Rvalue (C++11 et ultérieur)

Nouveauté C++11

Avec C++11 est venu un nouveau type de référence appelé référence rvalue. Cette référence peut lier et modifier des objets temporaires (rvalues), tels que des valeurs littérales et des valeurs de retour de fonction.

Une référence rvalue est formée en plaçant deux esperluettes (&&) après le type.

Exemple 5 : Référence rvalue

int&& ref = 1 + 2;  // référence rvalue vers le résultat temporaire de 1+2

La référence rvalue prolonge la durée de vie de l'objet temporaire et lui permet d'être utilisé comme une variable ordinaire.

Exemple 6 : Utilisation d'une référence rvalue

int&& ref = 1 + 2;
ref += 3;           // modifie le temporaire
cout << ref;        // affiche 6
Sortie
6
Avantage des références rvalue

Les références rvalue permettent d'éviter les copies inutiles lorsqu'il s'agit d'objets temporaires. Cela offre de meilleures performances, en particulier lors de la gestion de types plus volumineux, tels que des chaînes et des objets.

Elles sont à la base de la sémantique de déplacement (move semantics) introduite en C++11.

Comparaison des types de références

TypeSyntaxePeut référencerUsage typique
Référence lvaluetype&Variables modifiables (lvalues)Paramètres de fonction, alias
Référence const lvalueconst type&Variables et temporaires (lecture seule)Paramètres pour éviter les copies
Référence rvaluetype&&Temporaires (rvalues)Sémantique de déplacement, perfect forwarding
 Exercice pratique

Manipulation de références

 Niveau : Débutant

Considérez le code suivant :

int a = 10;
int b = 20;

int& ref = a;
ref = b;  // Que se passe-t-il ici ?

cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "ref = " << ref << endl;

Questions :

  1. Quelles sont les valeurs affichées ?
  2. Que signifie l'instruction ref = b; ?
  3. La référence ref est-elle maintenant un alias pour b ?
  4. Modifiez le code pour échanger les valeurs de a et b en utilisant une référence.
Points clés à retenir
  • Une référence est un alias pour une variable existante (déclarée avec &).
  • Une référence doit être initialisée dès sa déclaration.
  • Une référence ne peut pas être réaffectée à une autre variable.
  • Une référence n'a pas d'adresse propre (son adresse est celle de la variable référencée).
  • Les références sont plus sûres que les pointeurs car elles ne peuvent pas être nulles (mais attention aux références invalides).
  • Les références rvalue (&&) permettent de lier des temporaires et sont à la base de la sémantique de déplacement.
  • Les références sont très utilisées comme paramètres de fonctions pour éviter les copies et permettre les modifications.
  • Règle générale : préférer une référence à un pointeur quand la réaffectation n'est pas nécessaire.

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.