Déclaration d'un enum au sein d'une classe
Dans l'extrait de code suivant, le Color
enum est déclaré dans la Car
classe afin de limiter le champ d'application de l'enum et d'essayer de ne pas "polluer" l'espace de noms global.
class Car
{
public:
enum Color
{
RED,
BLUE,
WHITE
};
void SetColor( Car::Color color )
{
_color = color;
}
Car::Color GetColor() const
{
return _color;
}
private:
Car::Color _color;
};
(1) Est-ce un bon moyen de limiter le champ d'application de la Color
enum? Ou, dois-je le déclarer à l'extérieur de la Car
classe, mais peut-être à l'intérieur de son propre espace de noms ou structure? Je viens de tomber sur cet article d'aujourd'hui, qui prône le dernier et discute certains points de nice sur les énumérations: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums.
(2) Dans cet exemple, lorsque vous travaillez dans la classe, est-il préférable de code de l'énumération que Car::Color
, ou serait tout simplement Color
suffit-il? (Je suppose que le premier est mieux, juste au cas où il y a un autre Color
enum déclarés dans l'espace de noms global. De cette façon, au moins, nous sommes explicite au sujet de l'énumération, nous nous référons.)
Vous devez vous connecter pour publier un commentaire.
Si
Color
est quelque chose qui est spécifique à justeCar
s alors que c'est la façon de limiter son champ d'application. Si vous allez avoir une autreColor
enum que les autres classes d'utilisation, alors vous pourriez aussi bien le faire global (ou au moins en dehors deCar
).Il ne fait aucune différence. Si il n'y est mondiale, puis le local est encore utilisé de toute façon car il est plus proche du champ d'application actuel. Notez que si vous définissez celles de la fonction en dehors de la définition de la classe, alors vous aurez besoin de spécifier explicitement
Car::Color
dans la fonction de l'interface.Car::Color getColor()
maisvoid Car::setColor(Color c)
parce que danssetColor
nous avons déjà le spécificateur.Aujourd'hui - à l'aide de C++11 - vous pouvez utiliser enum class pour cela:
AFAII c'est exactement ce que vous voulez.
Je préfère l'approche suivante (code ci-dessous).
Il résout le "espace de noms de la pollution" problème, mais il est aussi beaucoup plus typesafe (vous ne pouvez pas attribuer et même comparer les deux énumérations, ou votre énumération avec tous les autres types intégrés, etc).
Utilisation:
J'ai créer une macro pour en faciliter l'utilisation:
Utilisation:
Quelques références:
if(c2 == Color::Red )
est raisonnable et doit compiler, mais dans votre exemple, il ne le fait pas. Même argument pour l'affectation également!Color2
), alors pourquoi pensez-vousc2 == Color::Red
et affectations devraient compiler? Que faire siColor::Red
est 1, etColor2::Red
est 2? DevraitColor::Red == Color2::Red
évaluer àtrue
oufalse
? Si vous mélangez les non-typesafe agents recenseurs, tu vas passer un mauvais moment.c2
est de type différent! Maintenant, ce post fait sens pour moi. Merci. (+1)En général, je mets toujours mes énumérations dans un
struct
. J'ai vu plusieurs des lignes directrices, y compris "préfixer".Toujours pensé que cela ressemblait plus à
C
lignes directrices queC++
(pour une raison de l'abréviation et aussi parce que les espaces de noms dansC++
).Afin de limiter la portée, nous avons maintenant deux alternatives:
Personnellement, j'ai tendance à utiliser une
struct
car il peut être utilisé en tant que paramètres pour le modèle de programmation tout en un espace de noms ne peuvent pas être manipulés.Exemples de manipulation comprennent:
qui renvoie le nombre d'éléments d'enum à l'intérieur de la structure
T
🙂Si vous créez une bibliothèque de code, alors je voudrais utiliser l'espace de noms. Cependant, vous pouvez toujours avoir seulement un enum Couleur à l'intérieur de cet espace de noms. Si vous avez besoin d'un enum qui pourraient utiliser un nom commun, mais qui peuvent avoir différentes constantes pour les différentes classes, utilisez votre approche.