Unions et risques associés
Partager la mémoire entre plusieurs types
Unions et risques associés est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C++ Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C++ Academy comprend 4 leçons au total.
Qu'est-ce qu'une union ?
Une union permet à plusieurs membres de partager la même zone mémoire. Un seul membre est valide à la fois et l'union n'est pas plus grande que son membre le plus volumineux.
#include <iostream>
union Number {
int i;
float f;
};
int main() {
Number n;
n.i = 42;
std::cout << n.i << "\n";
}Taille d'une union
Comme les membres se chevauchent, la taille d'une union, obtenue avec sizeof, est égale à celle de son membre le plus volumineux (à laquelle peuvent s'ajouter des octets de remplissage liés à l'alignement), et non à leur somme.
#include <iostream>
union Mix { char c; int i; double d; };
int main() {
std::cout << sizeof(Mix) << "\n"; // size of double (often 8)
}Écrire dans un membre et en lire un autre
Écrire dans un membre et en lire un autre constitue le risque principal. Les bits sont réinterprétés, ce qui produit généralement un comportement indéfini ou surprenant.
#include <iostream>
union Bits { int i; float f; };
int main() {
Bits b;
b.f = 1.0f;
std::cout << b.i << "\n"; // reads float bits as int
}Un seul membre actif
Le membre dans lequel vous avez écrit en dernier est le seul que vous pouvez lire sans risque. Vous devez vous-même suivre le membre « actif » ; l’union ne le mémorise pas.
#include <iostream>
union Value { int i; double d; };
int main() {
Value v;
v.d = 3.14; // d is active
std::cout << v.d << "\n";
}Le modèle de l’union étiquetée
Pour utiliser les unions en toute sécurité, associez-les à une étiquette (une énumération) qui enregistre le membre actif. Il s’agit de l’ancêtre manuel de std::variant.
#include <iostream>
struct Tagged {
enum { Int, Double } tag;
union { int i; double d; };
};
int main() {
Tagged t; t.tag = Tagged::Int; t.i = 7;
if (t.tag == Tagged::Int) std::cout << t.i << "\n";
}Lire le bon membre
Faites toujours un branchement sur l’étiquette avant de lire. Lire le mauvais membre produit des valeurs incohérentes.
#include <iostream>
struct Tagged {
enum { Int, Double } tag;
union { int i; double d; };
};
void print(const Tagged& t) {
if (t.tag == Tagged::Int) std::cout << "int " << t.i << "\n";
else std::cout << "double " << t.d << "\n";
}
int main() { Tagged t{Tagged::Double}; t.d = 2.5; print(t); }Membres non triviaux
Placer dans une union un membre doté d’un constructeur ou d’un destructeur (comme std::string) exige une construction et une destruction manuelles. Cette approche est source d’erreurs, ce qui constitue une autre raison de préférer std::variant.
Unions anonymes
Une union anonyme n’a pas de nom ; ses membres sont accessibles directement. Elle est pratique à l’intérieur d’une structure, mais la même règle du membre actif s’applique.
#include <iostream>
struct Packet {
int kind;
union { int code; char letter; };
};
int main() {
Packet p; p.kind = 1; p.code = 99;
std::cout << p.code << "\n";
}Pourquoi les unions sont risquées
Résumé des dangers :
- Aucune mémorisation du membre actif.
- Lire un membre inactif constitue un comportement indéfini.
- Les types non triviaux nécessitent une gestion manuelle de leur durée de vie.
Quand les unions restent utiles
Les unions restent utiles pour le travail de bas niveau : réinterpréter des octets, économiser de la mémoire dans du code embarqué soumis à de fortes contraintes ou respecter un agencement binaire fixe. Pour les données courantes correspondant à « un type parmi plusieurs », préférez l’alternative plus sûre.
Vers std::variant
std::variant est une union sûre du point de vue des types qui suit pour vous le type actif et lève une exception si vous accédez au mauvais type. La suite de ce cours l’étudie.
Vérification rapide
Vérifiez votre compréhension des unions.
Récapitulatif
Vous avez découvert les unions :
- Tous les membres partagent un même bloc de mémoire.
- Seul le membre écrit en dernier peut être lu de manière valide.
- Utilisez une étiquette (une énumération) pour suivre le membre actif.
- Préférez
std::variantpour garantir la sécurité dans le C++ moderne.
Questions Fréquemment Posées
La leçon « Unions et risques associés » est-elle gratuite ?
Oui — le texte complet de « Unions et risques associés » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C++ Academy, passe à CoddyKit PRO. Le cours C++ Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Unions et risques associés » ?
Partager la mémoire entre plusieurs types Tu pratiques C++ Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C++ Academy ?
Aucune expérience préalable n'est requise. C++ Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Unions et risques associés » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C++ Academy ?
Oui. Chaque leçon C++ Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Classe enum à portée limitée
- Unions et risques associés
- std::variant
- std::visit