Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
enum_class [2016/05/23 15:56] sylvie-c [Notion de portée] |
enum_class [2016/08/23 00:45] (Version actuelle) gbdivers |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
^ [[rvalue_et_lvalue|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[inference_de_type|Chapitre suivant]] ^ | ^ [[rvalue_et_lvalue|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[inference_de_type|Chapitre suivant]] ^ | ||
+ | |||
+ | <note warning>Les chapitres suivants sont encore en cours de rédaction, voire à l'état d'ébauche. N’hésitez pas a faire des remarques ou poser des questions sur le forum de [[http://zestedesavoir.com/forums/|Zeste de Savoir]] ou de [[http://openclassrooms.com/forum/sujet/nouveau-cours-c-moderne|OpenClassroom]].</note> | ||
====== Constantes et énumérations ====== | ====== Constantes et énumérations ====== | ||
Ligne 15: | Ligne 17: | ||
</code> | </code> | ||
- | Signifie que l'on cree un constante "pi", qui prend la valeur "3.1415...". Le type de cette constante depend | + | Signifie que l'on cree un constante "pi", qui prend la valeur "3.1415...". Le type de cette constante depend de T, qui représente un type fondamental, comme int, double, etc... |
Ligne 33: | Ligne 35: | ||
- | ===== énumérations ===== | + | ===== Les enumérations ===== |
- | Plusieurs constantes, regroupees dans un meme scope. | + | Une enumeration est une liste de valeurs constantes. Chaque valeur a un nom et l'ensemble des noms sont regroupes dans le nom de l'enumeration. |
+ | |||
+ | Pour declarer une enumeration et des valeurs, la syntaxe generale est la suivante : | ||
<code cpp> | <code cpp> | ||
- | enum class MyEnum { | + | enum class NOM_ENUMERATION { |
- | value_1 = 123, | + | LISTE_DE_VALEURS |
- | value_2 = 456 | + | |
}; | }; | ||
</code> | </code> | ||
- | Utilisation : avec operateur de portee ''::'' | + | Le nom de l'enumeration est "NOM_ENUMERATION". Par exemple, pour definir une enumeration de couleurs (vide pour le moment) : |
<code cpp> | <code cpp> | ||
- | int x = MyEnum::value_1; | + | enum class Couleur { |
+ | ... | ||
+ | }; | ||
</code> | </code> | ||
- | <note>**Anciennes syntaxe**s | + | La liste de valeurs est une liste d'identifiants separees par des virgules. |
- | Sans le mot cle ''class''. Definie les enum dans la portee globale. | + | <code cpp> |
- | </note> | + | NOM_VAlEUR_1, NOM_VALEUR_2, ..., NOM_VALEUR_N |
+ | </code> | ||
- | ===== Notion de portée ===== | + | Par exemple : |
<code cpp> | <code cpp> | ||
- | enum class MyEnum { | + | enum class Couleur { |
- | value_1 = 123 | + | Noir, Blanc, Rouge, Jaune, Bleu, Orange, Vert, Violet |
}; | }; | ||
+ | </code> | ||
- | int value_1 = 456; | + | (Note : pour rappel, les retours a la ligne sont utilises librement en C++. Cette liste est definie sur une seule ligne, mais ca serait equivalent d'ecrire chaque valeur sur une ligne differente). |
+ | |||
+ | Dans cet exemple, l'enumeration s'appelle ''Couleur''. Elle contient 8 valeurs : ''Noir'' a ''Violet''. | ||
+ | |||
+ | Une enumeration definie un nouveau type, il est donc possible de definir une variable du type "NOM_ENUMERATION". Pour utiliser les valeurs definies dans une enumeration, il faut simplement utiliser l'operateur de portee ''::'' (scope operator). | ||
+ | |||
+ | <code cpp> | ||
+ | NOM_ENUMERATION NOM_VARIABLE {}; | ||
+ | NOM_VARIABLE = NOM_ENUMERATION :: NOM_VALEUR; | ||
</code> | </code> | ||
- | L'identifiant ''value_1'' est defini 2 fois. Dans les regles de nommage, on a dit que chaque identifiant devait etre defini 1 seule fois, pourquoi cela fonctionne ? Par ce qu'ils sont dans des portees differentes. | + | Par exemple : |
- | <code cpp main.cpp> | + | <code cpp> |
- | #include <iostream> | + | enum class Couleur { |
- | + | Noir, Blanc, Rouge, Jaune, Bleu, Orange, Vert, Violet | |
- | int main() { | + | }; |
- | enum class MyEnum { | + | |
- | value_1 = 123 | + | Couleur une_couleur { Couleur::Rouge }; // initialisation |
- | }; | + | une_couleur = Couleur::Bleu; // affectation |
- | + | ||
- | int value_1 = 456; | + | |
- | + | ||
- | std::cout << value_1 << std::endl; | + | |
- | std::cout << MyEnum::value_1 << std::endl; | + | |
- | } | + | |
</code> | </code> | ||
+ | Les valeurs des enumerations peuvent etre converties en nombre entier, en utilisant l'operateur de conversion "static_cast" : | ||
+ | <code cpp> | ||
+ | const auto c = static_cast<int>(une_couleur); // convertie le type "Couleur" en type "int" | ||
+ | </code> | ||
+ | |||
+ | Par defaut, les valeurs de l'enumeration sont converties en entier selon leur ordre dans l'enumeration, en commencant de 0 : | ||
+ | |||
+ | <code cpp> | ||
+ | std::cout << static_cast<int>(Couleur::Noir) << std::endl; | ||
+ | std::cout << static_cast<int>(Couleur::Blanc) << std::endl; | ||
+ | std::cout << static_cast<int>(Couleur::Rouge) << std::endl; | ||
+ | std::cout << static_cast<int>(Couleur::Vert) << std::endl; | ||
+ | </code> | ||
+ | |||
+ | affiche : | ||
+ | |||
+ | <code> | ||
+ | 0 | ||
+ | 1 | ||
+ | 2 | ||
+ | 6 | ||
+ | </code> | ||
+ | |||
+ | Il est possible de definir la valeur entiere correspondant a chaque valeur de l'enumeration en utilisant =. Les valeurs qui ne sont pas explicitement definies prennent la valeur precedente + 1. | ||
+ | |||
+ | <code cpp> | ||
+ | enum class Couleur { | ||
+ | Noir, // prend automatiquement la valeur 0 | ||
+ | Blanc, // prend automatiquement la valeur 1 | ||
+ | Rouge = 100, // prend explicitement la valeur 100 | ||
+ | Jaune = 200, // prend explicitement la valeur 200 | ||
+ | Bleu, // prend automatiquement la valeur 201 | ||
+ | Orange, // prend automatiquement la valeur 202 | ||
+ | Vert, // prend automatiquement la valeur 203 | ||
+ | Violet // prend automatiquement la valeur 204 | ||
+ | }; | ||
+ | |||
+ | std::cout << static_cast<int>(Couleur::Rouge) << std::endl; | ||
+ | std::cout << static_cast<int>(Couleur::Vert) << std::endl; | ||
+ | </code> | ||
+ | |||
+ | affiche : | ||
+ | |||
+ | <code> | ||
+ | 100 | ||
+ | 203 | ||
+ | </code> | ||
+ | |||
+ | Il est également possible de convertir un nombre entier en valeur d'une enumeration avec "static_cast". | ||
+ | |||
+ | <code cpp> | ||
+ | const auto c = static_cast<Couleur>(1); | ||
+ | assert(c == Couleur::Blanc); | ||
+ | </code> | ||
+ | |||
+ | <note>**Ancienne syntaxe** | ||
+ | |||
+ | Meme syntaxe, sans le mot-clé ''class''. | ||
+ | |||
+ | <code cpp> | ||
+ | enum Couleur { | ||
+ | Noir, Blanc, Rouge, Jaune, Bleu, Orange, Vert, Violet | ||
+ | }; | ||
+ | |||
+ | Couleur une_couleur { Rouge }; // initialisation | ||
+ | une_couleur = Bleu; // affectation | ||
+ | </code> | ||
+ | |||
+ | Definit les enum dans la portee globale (//unscoped enum//). "Dans la portée globale" signifie qu'il n'est pas nécessaire d'indiquer la portée ''Couleur::''. Cela peut provoquer des conflits, par exemple : | ||
+ | |||
+ | <code cpp> | ||
+ | enum Pion { | ||
+ | Noir, Blanc | ||
+ | }; | ||
+ | |||
+ | enum Couleur { | ||
+ | Noir, Blanc, Rouge, Jaune, Bleu, Orange, Vert, Violet // confit | ||
+ | }; | ||
+ | </code> | ||
+ | affiche les erreurs suivantes : | ||
+ | |||
+ | <code> | ||
+ | main.cpp:8:5: error: redefinition of enumerator 'Noir' | ||
+ | Noir, Blanc, Rouge, Jaune, Bleu, Orange, Vert, Violet // confit | ||
+ | ^ | ||
+ | main.cpp:4:5: note: previous definition is here | ||
+ | Noir, Blanc | ||
+ | ^ | ||
+ | main.cpp:8:11: error: redefinition of enumerator 'Blanc' | ||
+ | Noir, Blanc, Rouge, Jaune, Bleu, Orange, Vert, Violet // confit | ||
+ | ^ | ||
+ | main.cpp:4:11: note: previous definition is here | ||
+ | Noir, Blanc | ||
+ | ^ | ||
+ | </code> | ||
+ | |||
+ | Ce type d'énumération ne nécessite pas de conversion explicite avec ''static_cast'' pour convertir en entier, les valeurs sont convertie implicitement (promotion) entiers. | ||
+ | </note> | ||
^ [[rvalue_et_lvalue|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[inference_de_type|Chapitre suivant]] ^ | ^ [[rvalue_et_lvalue|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[inference_de_type|Chapitre suivant]] ^ | ||
+ |