Références en C++

Jinku Hu 12 octobre 2023
  1. Utilisez la notation & attr(optional) declarator pour déclarer une référence lvalue en C++
  2. Utiliser des références pour implémenter des prototypes de fonction en C++
Références en C++

Cet article montre les différentes méthodes d’utilisation des références en C++.

Utilisez la notation & attr(optional) declarator pour déclarer une référence lvalue en C++

Les références définissent des noms alternatifs pour les objets. Ce ne sont pas des objets eux-mêmes, et par conséquent, nous ne pouvons pas avoir de tableaux de références ou de pointeurs vers des références. Les références se réfèrent uniquement à des objets déjà existants, et elles sont liées à ces objets, ce qui implique qu’aucune modification n’est autorisée après la déclaration.

De plus, les références doivent être initialisées et lorsque l’opération est effectuée à l’aide des noms de référence, les objets liés sont modifiés. Notez que cette dernière caractéristique les rend assez similaires aux pointeurs. Nous pouvons considérer les références comme des alternatives aux pointeurs, sauf que les premières peuvent être utilisées comme noms de variables ordinaires sans notation de déréférencement pour accéder à la valeur de l’objet correspondant. Si l’on veut imiter le comportement des références, on peut déclarer un pointeur const vers le type donné. Cette dernière se caractérise par les mêmes caractéristiques que les références à l’exception de la notation d’accès aux valeurs.

Dans l’exemple de code suivant, la variable xr est déclarée comme référence à un x, représentant un objet int. Une fois que xr est initialisé lors de la déclaration, il ne peut pas être réaffecté pour faire référence à un objet différent de quelque type que ce soit. D’autre part, nous pouvons définir différents noms d’alias tels que xr pour le même objet auquel il fait référence. A savoir, xrc est une référence qualifiée const ce qui signifie que la valeur de l’objet correspondant est uniquement accessible et ne peut pas être modifiée à l’aide du nom d’alias.

#include <iostream>

using std::cout;
using std::endl;

int main() {
  int x = 5;
  int& xr = x;
  const int& xrc = x;

  xr *= xr;
  //    xrc *= x; Error
  cout << "xr: " << xr << endl;
  cout << "xrc: " << xrc << endl;

  return EXIT_SUCCESS;
}

Production:

xr : 25 xrc : 25

Nous pouvons déclarer plusieurs références au même objet, comme illustré dans l’extrait de code suivant. Néanmoins, il faut savoir que les modifications de l’un des alias affecteront le même objet.

#include <iostream>

using std::cout;
using std::endl;

int main() {
  int x = 5;
  int& xr = x;
  int& xrr = x;

  xr *= xr;
  xrr *= xrr;
  cout << "xr: " << xr << endl;
  cout << "xrr: " << xrr << endl;

  return EXIT_SUCCESS;
}

Production:

xr : 625 xrr : 625

Utiliser des références pour implémenter des prototypes de fonction en C++

Les références sont principalement utilisées pour fournir des interfaces de fonctions plus propres, mais aussi parce que le langage C++ fournit des capacités de surcharge d’opérateurs, et la notation doit être la même pour tous les opérateurs. Cette dernière serait compliquée s’il n’y avait pas de concepts de référence dans la langue. Ainsi, utiliser les opérateurs qui doivent prendre des arguments comme pointeurs aurait pu ressembler à ++&x.

Les fonctions qui doivent prendre des objets pour accéder aux valeurs peuvent spécifier les arguments correspondants en tant que références const et si la modification est également requise sans const. Par exemple, la fonction printVector prend une référence const à std::vector pour imprimer les éléments dans le flux cout, mais swapElements doit échanger chaque élément, nous devons donc avoir une référence régulière à L’object.

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::endl;
using std::setw;
using std::string;
using std::vector;

template <typename T>
void printVector(const vector<T> &vec) {
  for (auto &i : vec) {
    cout << i << "; ";
  }
  cout << endl;
}

template <typename T>
void swapElements(vector<T> &vec) {
  for (auto iter = vec.begin(); iter < vec.end() - 1; ++iter) {
    std::swap(*iter, *(iter + 1));
  }
}

int main() {
  vector<int> vec1 = {43, 5, 123, 94, 359, -23, 2, -1};

  printVector(vec1);
  swapElements(vec1);
  printVector(vec1);

  return EXIT_SUCCESS;
}

Production:

43;
5;
123;
94;
359;
- 23;
2;
- 1;
5;
123;
94;
359;
- 23;
2;
- 1;
43

Notez que tous les exemples de références précédents, y compris ceux const, sont appelés références lvalue. Ces références sont utilisées pour faire référence aux objets qui doivent conserver des valeurs valides après y avoir accédé ou modifié. Le langage C++ fournit également des références rvalue, qui sont utilisées pour faire référence aux objets temporaires.

Un objet temporaire est une hypothèse pour le programmeur que l’objet donné ne sera plus utilisé. Les références rvalue sont spécifiées à l’aide de la notation && attr(optional) declarator et les objets sont accessibles comme les références lvalue. Les références Rvalue sont utilisées pour implémenter des opérations efficaces, comme déplacer le constructeur et déplacer l’affectation pour éviter des copies coûteuses d’objets volumineux.

Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Article connexe - C++ Reference