Enum la portée des questions
J'essaie de garder les choses aussi local que possible, j'ai donc mis les énumérations à portée de classe, même si elles sont partagées entre deux classes (je l'ai mis dans la classe qui "va mieux" avec elle.) Cela a très bien fonctionné, mais j'ai récemment rencontré un problème où une dépendance circulaire va se produire si j'ai mis l'enum à portée de classe.
L'enum est va être un argument du constructeur pour plusieurs classes, et la classe il est (et de la classe qui fait le plus de sens pour lui d'être dans) comprend les classes. Ainsi, il n'est pas possible d'utiliser les enum comme un argument du constructeur pour les classes incluses, car elle aura pour conséquence une dépendance circulaire.
Serait-il mieux de mettre juste ce enum dans son propre fichier d'en-tête, et si oui, dois-je mettre toutes les énumérations dans le fichier d'en-tête pour être cohérent? Existe-il d'autres solutions à ce problème (c'est logique)?
- avez-vous essayé de déclaration?
- Avant les déclarations seulement vous permettre d'accéder le nom du type. Vous ne pouvez pas accéder à l'interface ou de l'instancier ou de faire quelque chose comme ça.
Vous devez vous connecter pour publier un commentaire.
si l'enum est utilisé par plusieurs classes, alors je dirais qu'il n'appartient pas vraiment à la définition d'une classe unique, mais dans l'espace de noms dans lequel les classes de résidence.
c'est moins que l'énumération est passé par une classe du constructeur de l'autre, auquel cas il peut faire plus de sens pour instancier l'enum charge de la classe séparément et de les passer en paramètre au constructeur de la classe conteneur.
Depuis C++11, vous pouvez utiliser un
enum class
(ouenum struct
- la même chose, a déclaré différemment), où les valeurs enum sont limitées à l'enum nom. Par exemple, ici, est valide en C++11 de la déclaration.Pour accéder aux valeurs de l'enum, cependant, vous devez portée correctement à l'aide de la
::
de l'opérateur. Donc, c'est une assignation valide en C++11:Mais ce n'est pas:
Cela résout le conflit de noms, et signifie que vous n'avez pas à utiliser le conteneur de l'espace de noms ou struct juste pour arrêter la portée des valeurs qui fuit à l'endroit où ils ne devraient pas. Cela signifie que l'enum ci-dessous peuvent exister dans le même champ d'application que
token_type
:Maintenant les deux valeurs appelé
identifier
différente dans les deux structures ne sera pas interférer.J'utilise une variante de ce que Michael et Roger n':
Je trouve
Color::Type
à être plus joli et plus d'auto-documentation deColor::Color
ouCOLOR::Color
. Si vous trouvezColor::Type
trop verbeux, vous pouvez utiliserColor::T
.Je n'ai pas de préfixe de mes valeurs énumérées (c'est à dire
COLOR_RED
) parce que l'espace de noms autour de l'enum devient le préfixe.J'ai arrêté à l'aide de la ALL_CAPS convention pour mon étendue de constantes car ils se heurtent à des macros en C des bibliothèques (par exemple, la valeur NULL). Les Macros ne sont pas étendues dans les espaces de noms qu'ils sont définis dans.
J'ai souvent mis mes énumérations dans un espace de noms pour éviter les différentes valeurs enum d'encombrer l'espace de noms global. Je pense que c'est ce que vous essayez de le faire en les mettant dans une classe. Mais si ils ne correspondez pas bien dans une classe, un espace de noms fonctionne assez bien juste pour ce but:
J'ai un extrait de l'éditeur, qui fabrique les grandes lignes d'une nouvelle énumération, compte tenu de son nom, y compris le
ligne qui crée un typedef, donc c'est un peu plus lisible de déclarer les variables avec l'énumération du type.
Je soupçonne que Stroustrup aurait fait la valeur de l'énumération des noms limitées à l'énumération s'il en avait l'occasion, mais C compatibilité forcé sa main (c'est juste de la spéculation - peut-être qu'un jour je vais regarder dans D&E et voir s'il parle de quoi que ce soit).
MyEnum_t
pour se référer à l'enum comme un type, etMyEnum::a
,MyEnum::b
à se référer à ses membres, comme si l'enum étaient un type de regroupement. J'ai expérimenté un certain temps avant de choisir la particulier les conventions de nommage ici et j'ai plus de temps pour être aussi bon que je peux faire.Vous devez placer les enum, en dehors de toute classe, si elle est partagée, mais vous pouvez encore le champ d'application du protocole enum. Le placer dans l'espace de noms afin de les agents recenseurs ne pas "fuir", qui encombrent votre projet d'espace de noms:
using
s=déclaration comme vous le faites pour voir si je l'aime mieux que latypedef
mess que j'ai utilisé. Je pense que je vais l'aime (mais peut utiliser une autre convention de nommage que tous les chapeaux pour le type enum). Merci!typedef COLOR::Color Color;
est équivalent àusing COLOR::Color;
ici.Je suis d'accord avec Emile. Une autre option si vous êtes à l'aide de C++98 est d'utiliser struct au lieu de espace de noms, comme suit
Je préfère depuis idéalement, j'aimerais utiliser un espace de noms pour représenter un module qui contient plusieurs classes, plutôt que de simplement la portée d'un enum ...
Vous pouvez essayer de le déclarer avant la enum comme ceci:
enum class
(ouenum struct
), mais ils sont distincts de style ancienenum
s.