Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Langage C++
  3. Unions, unions illimitées
Extrait - Langage C++ De l'héritage C au C++ moderne (avec programmes d'illustration) (2e édition)
Extraits du livre
Langage C++ De l'héritage C au C++ moderne (avec programmes d'illustration) (2e édition) Revenir à la page d'achat du livre

Unions, unions illimitées

Principe

Jusqu’à la norme C++11, l’union ne présente pas de différence entre C et C++. La définition donnée par Bjarne Stroustrup est la suivante : "Une union est une struct dans laquelle tous les membres sont alloués à la même adresse. Cela signifie que la quantité de mémoire occupée par l’union se limite à la taille de son membre le plus large. Cela implique qu’une union ne puisse contenir la valeur que d’un seul membre à un moment donné."

Ainsi, une union se traduit-elle par une variable unique qui dispose d’un choix de types. Le programmeur définit son choix de types et l’espace mémoire total de la variable correspond à celui nécessaire pour le type le plus grand. Par exemple :

union utest{ 
    char c; 
    int i; 
    float f; 
    double d; 
}; 

Pour disposer d’une variable du type de notre union, en C++ il suffit d’une déclaration :

utest u ; 

Cette union utest définit le type d’une variable qui peut être soit un char, soit une int, soit un float, soit un double. Dans tous les cas, la taille en mémoire de la variable sera celle d’un double. Le choix du type pour la variable s’effectue en utilisant l’opérateur point comme pour une structure. Le choix du type détermine la zone de mémoire réservée selon ce type sur le total de mémoire réservé par l’union. Par exemple :

L’expression

u.c = 'A'; 

détermine que l’union est un char, ce qui utilise un seul octet, le premier, sur l’espace mémoire total de l’union.

Avec :

u.i = 350; 

l’union est un int qui utilise les quatre premiers...

Union de structures

Une union peut contenir des structures et, depuis C++11, avec tout ce qui constitue les caractéristiques d’une classe.

Expérimentation :

#include <iostream> 
struct Coord { int x, y; }; 
struct Pix{ float x, y, color;}; 
 
union Position { 
    Coord coord; 
    Pix pix; 
}; 
 
int main() 
{ 
    Position p; 
    p.coord = { 10,20 };    // le = est ici obligatoire en C et C++ 
    std::cout << p.coord.x << ", "  
           << p.coord.y << '\n'; 
 
    p.pix = { 30.0f,40.0f,55.55f }; 
    std::cout << p.pix.x << ", " << p.pix.y  
           << ", " << p.pix.color << '\n'; 
 
    std::cin.get(); 
    return 0; 
} 

Dans une union, l’utilisation de l’opérateur = est obligatoire pour initialiser les structures. Dans cet exemple, la seconde initialisation écrase les valeurs de la première puisqu’au final il n’y a qu’une structure.

Union discriminée

Une structure peut contenir une union de structures ainsi qu’un identificateur qui permet de connaître le type choisi dans l’union pour l’instance d’une de ses structures. C’est ce que l’on appelle une union discriminée. En voici un exemple inspiré d’un programme trouvé dans la documentation MSDN de Microsoft.

De façon schématique, il s’agit de retracer les données de température et de vent relatives au temps qu’il fait.

Nous avons deux types de structures, l’un pour des données de température, l’autre pour les données du vent :

struct Temperature  
{ 
    int idStation; 
    int min, max, actuelle; 
}; 
struct Vent  
{ 
    int idStation; 
    int vitesse; 
    int direction; 
}; 

Ces deux types de structures sont identifiés chacun par une constante dans une énumération à part :

enum TypeData{TEMPERATURE, VENT, MAXTYPE}; 

Une troisième structure nommée Data contient une union anonyme (sans nom) composée des deux structures pour la température et le vent. La structure Data contient également une variable de type TypeData qui permettra d’identifier le type de la structure qui sera effectivement instanciée dans l’union :

struct Data  
{ 
    TypeData type; 
    union  
    { 
        Temperature temp; 
        Vent vent; 
    }; 
}; 

Pour chacune des structures composant l’union, nous écrivons deux fonctions :...

Union illimitée (C++11)

La norme C++ 2011 lève l’impossibilité d’utiliser dans une union des classes complètes avec constructeurs, destructeurs, fonctions, etc. L’union en principe n’a plus de limite. Nous pouvons reprendre l’exemple météo précédent en considérant les structures de température et de vent comme des classes plutôt que comme des structures C.

Pour les trois classes Temperature, Vent et Data :

#include <iostream>  

La classe pour les températures :

struct Temperature 
{ 
    int idStation; 
    int min, max, actuelle; 
 
    Temperature(); 
    void Affiche(); 
}; 
Temperature::Temperature() 
{ 
    idStation = rand() % 10; 
    actuelle = rand() % 120 - 40; 
    min = -rand() % 40; 
    if (min > actuelle) 
        min = actuelle; 
    max = rand() % 80; 
    if (max < actuelle) 
        max = actuelle; 
}   
void Temperature::Affiche() 
{ 
    using namespace std; 
    cout << "TEMPERATURE :\n"; 
    cout << "idStation : " << idStation << '\n'; 
    cout << "Actuelle : " << actuelle << '\n'; 
    cout << "Min : " << min << '\n'; 
    cout << "Max : " << max << '\n'; 
    cout...