Dans l'extrait de code suivant, l' Color
énumération est déclarée dans la Car
classe afin de limiter la portée de l'énumération 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 la portée de l' Color
énumération? Ou devrais-je le déclarer en dehors de la Car
classe, mais éventuellement dans son propre espace de noms ou structure? Je viens de tomber sur cet article aujourd'hui, qui prône ce dernier et discute de quelques points intéressants sur les énumérations: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums .
(2) Dans cet exemple, lorsque vous travaillez au sein de la classe, est-il préférable de coder l'énumération comme Car::Color
, ou Color
suffirait-il? (Je suppose que le premier est meilleur, juste au cas où il y aurait une autre Color
énumération déclarée dans l'espace de noms global. De cette façon, au moins, nous sommes explicites sur l'énumération à laquelle nous faisons référence.)
Car::Color getColor()
maisvoid Car::setColor(Color c)
parce quesetColor
nous avons déjà le spécificateur.De nos jours - en utilisant C ++ 11 - vous pouvez utiliser la classe enum pour cela:
AFAII cela fait exactement ce que vous voulez.
la source
Je préfère l'approche suivante (code ci-dessous). Il résout le problème de la "pollution des espaces de noms", mais il est aussi beaucoup plus sûr de type (vous ne pouvez pas assigner et même comparer deux énumérations différentes, ou votre énumération avec d'autres types intégrés, etc.).
Usage:
Je crée une macro pour faciliter l'utilisation:
Usage:
Quelques références:
la source
if(c2 == Color::Red )
c'est raisonnable et doit compiler, mais dans votre exemple, il Même argument pour la cession aussi!c2
est d'un autre type (Color2
), alors pourquoi pensez-vous que lesc2 == Color::Red
affectations devraient être compilées? Et siColor::Red
vaut 1 etColor2::Red
2? DevraitColor::Red == Color2::Red
évaluertrue
oufalse
? Si vous mélangez des recenseurs non sécurisés, vous allez passer un mauvais moment.En général, je mets toujours mes énumérations dans un fichier
struct
. J'ai vu plusieurs directives, y compris le "préfixage".J'ai toujours pensé que cela ressemblait plus à des
C
directives qu'à des directivesC++
(d'une part à cause de l'abréviation et aussi à cause des espaces de noms dansC++
).Donc, pour limiter la portée, nous avons maintenant deux alternatives:
Personnellement, j'ai tendance à utiliser un
struct
car il peut être utilisé comme paramètres pour la programmation de modèles alors qu'un espace de noms ne peut pas être manipulé.Des exemples de manipulation comprennent:
qui renvoie le nombre d'éléments d'énumération à l'intérieur de la structure
T
:)la source
Si vous créez une bibliothèque de codes, j'utiliserais un espace de noms. Cependant, vous ne pouvez toujours avoir qu'une seule énumération Color dans cet espace de noms. Si vous avez besoin d'une énumération qui pourrait utiliser un nom commun, mais qui pourrait avoir des constantes différentes pour différentes classes, utilisez votre approche.
la source