ProgrammationDéveloppeur C++

Décrivez les principes de fonctionnement des pointeurs et des références en C++. Quelle est leur différence et quand les utiliser ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Histoire de la question :

Les pointeurs sont l'un des principaux outils en C++ depuis le début du langage, servant de base à la gestion de la mémoire et aux structures dynamiques, ainsi qu'à l'interaction avec les bibliothèques système de bas niveau. Les références ont été ajoutées plus tard (avec l'arrivée du C++) pour simplifier la syntaxe et augmenter la sécurité du code.

Problème :

Les erreurs d'utilisation de la mémoire sont l'un des problèmes les plus fréquents en C++, en particulier lors d'une mauvaise utilisation des pointeurs (pointeurs pendants, fuites de mémoire). Parfois, un débutant ne comprend pas dans quels cas utiliser une référence et dans quels cas utiliser un pointeur, ou suppose à tort qu'ils sont entièrement interchangeables.

Solution :

Un pointeur (T*) est une variable qui stocke l'adresse d'un objet, il peut être nullptr, supporte l'arithmétique, permet l'allocation et la désallocation dynamiques, et peut changer l'objet auquel il fait référence.

Une référence (T&) est un alias d'un autre objet existant. Les références doivent être initialisées lors de leur création, ne peuvent pas être "nulles" (référencer null), ne supportent pas l'arithmétique, mais sont plus pratiques et plus sûres (par exemple lors du passage à des fonctions).

Exemple de code :

void increment_pointer(int* p) { if(p) ++(*p); } void increment_reference(int& r) { ++r; } int main() { int a = 5; increment_pointer(&a); increment_reference(a); }

Caractéristiques clés :

  • Les pointeurs peuvent être redirigés, ce que les références ne peuvent pas
  • Une référence doit toujours être liée à un objet réel, un pointeur peut être nullptr
  • Les références sont souvent préférables lors du passage à une fonction, si une référence ne peut pas être utilisée, un pointeur est utilisé

Questions pièges.

Peut-on changer une référence après son initialisation pour qu'elle référence un autre objet ?

Non. Une référence en C++ est un alias constant. Après l'initialisation, la référence pointera toujours sur le même objet, contrairement à un pointeur qui peut être redirigé.

Exemple de code :

int a = 1; int b = 2; int& ref = a; // ref = b - assigne la valeur de b, mais ref continue de référencer a

Peut-on créer une "référence nulle" ou une référence à nullptr ?

Non, la norme n'autorise pas les références sur des objets inexistants. Cela mène à un comportement indéfini.

Exemple :

int* p = nullptr; // int& r = *p; - UB

Quelle est la différence entre int const ptr et const int ptr ?**

int* const ptr est un pointeur constant sur un int (le pointeur ne peut pas être redirigé, mais la valeur peut être changée). const int* ptr est un pointeur sur un int constant (le contenu pointé ne peut pas être modifié, mais le pointeur peut être redirigé).

Exemple de code :

int a = 1, b = 2; const int* ptr1 = &a; // *ptr1 ne peut pas être modifié, ptr1 = &b - possible int* const ptr2 = &a; // *ptr2 peut être modifié, ptr2 = &b - impossible

Erreurs typiques et anti-patterns

  • Utilisation de références sur des valeurs temporaires ou des objets déjà supprimés
  • Réallocation de mémoire sans reprovisionnement des pointeurs
  • Référence "nulle" - UB

Exemple de la vie

Cas négatif

Un jeune développeur a utilisé des pointeurs pour passer des paramètres, sans les vérifier pour nullptr, provoquant un arrêt brutal en cas d'erreurs.

Avantages :

  • Fonctionnait jusqu'à l'apparition d'erreurs

Inconvénients :

  • Pannes non évidentes lors d'appels incorrects
  • Difficulté à trouver des erreurs

Cas positif

Un développeur expérimenté a utilisé int& lorsque le passage est garanti et int* lorsque nullptr est possible, en vérifiant toujours le pointeur pour null.

Avantages :

  • Minimisation des erreurs de mémoire
  • Sémantique claire des fonctions

Inconvénients :

  • Parfois compliqué à gérer avec la mémoire dynamique