De Bjarne Stroustrup du C++11 FAQ:
L' enum class
es ("nouvelle enums", "fort enums") attaquer à trois problèmes
avec la traditionnelle C++ énumérations:
- conventionnelle
enum
s convertir implicitement int, à l'origine des erreurs quand quelqu'un ne veut pas d'une énumération d'agir comme un entier.
- conventionnelle
enum
à l'exportation de leurs agents recenseurs pour le reste de la portée, provoquant des collisions de noms.
- le type sous-jacent d'un
enum
ne peut pas être spécifié, de causer de la confusion, des problèmes de compatibilité, et fait en avant de la déclaration de
impossible.
La nouvelle enums sont "enum class", car ils combinent les aspects de la traditionnelle énumérations (noms de valeurs) avec des aspects de classes (dans l'étendue membres et absense de conversions).
Donc, comme mentionné par d'autres utilisateurs, le "fort des enums" permettrait de rendre le code plus sûr.
La seule chose que vous pouvez garantir à propos de "traditionnelles" enum
, c'est le fait que l'expression qui définit la valeur d'une constante d'énumération doit être une constante entière suffisamment grand pour contenir toutes les valeurs de l' enum
; c'est généralement un int
. Aussi chaque type énuméré est compatible avec char
ou un signed/unsigned integer.
C'est une grande description de ce qu'est un enum
doit être du type, de sorte que chaque compilateur va prendre decissions sur son propre sur le type de la traditionnelle enum
s et parfois, le résultat peut être surprenant.
Par exemple, j'ai vu du code comme ça un tas de fois:
enum E_MY_FAVOURITE_FRUITS
{
E_APPLE = 0x01,
E_WATERMELON = 0x02,
E_COCONUT = 0x04,
E_STRAWBERRY = 0x08,
E_CHERRY = 0x10,
E_PINEAPPLE = 0x20,
E_BANANA = 0x40,
E_MANGO = 0x80,
E_MY_FAVOURITE_FRUITS_FORCE8 = 0xFF // 'Force' 8bits, you're sure?
};
Dans le code ci-dessus, certains naïfs codeur est de penser que le compilateur va stocker l' E_MY_FAVOURITE_FRUITS
des valeurs dans un entier non signé 8 bits type... mais il n'y a aucune garantie à ce sujet, en ajoutant le champ E_MY_FAVOURITE_FRUITS_FORCE8
est un fardeau et ne force le compilateur à faire toute sorte de choix sur le type de l' enum
.
Si il y a un morceau de code qui s'appuient sur le type la taille et/ou suppose qu' E_MY_FAVOURITE_FRUITS
serait d'une certaine largeur (sérialisation des routines vient à mon avis) ce code peut se comporter dans d'étranges façons, selon le compilateur pensées.
Et pour empirer les choses, si certains collègue ajoute négligemment une nouvelle valeur à nos enum
:
E_DEVIL_FRUIT = 0x100, // New fruit, with value greater than 8bits
Le compilateur ne veut pas s'en plaindre! Il vient de se redimensionne le type pour s'adapter à toutes les valeurs de l' enum
(en supposant que le compilateur ont été en utilisant la plus petite possible, ce qui est une hypothèse que nous ne pouvons pas faire). Cette simple et peu plus de la enum
pourrait subtilité casser le code associé.
Mais ce problème est géré par l' enum class
es en permettant de spécifier le type:
enum class E_MY_FAVOURITE_FRUITS : unsigned char
{
E_APPLE = 0x01,
E_WATERMELON = 0x02,
E_COCONUT = 0x04,
E_STRAWBERRY = 0x08,
E_CHERRY = 0x10,
E_PINEAPPLE = 0x20,
E_BANANA = 0x40,
E_MANGO = 0x80,
E_DEVIL_FRUIT = 0x100, // Warning!: constant value truncated
};
Désormais, il est possible d'assurer un type (signés ou non) et de la largeur, de sorte que si un champ ont une expression hors de la plage de l' enum
nous allons être appréciée avec un avertissement (et le compilateur ne change pas le type de l' enum
).
Je pense que c'est une bonne amélioration de la sécurité.