c++ class enums namespaces scope

c++ - Declarar una enumeración dentro de una clase



class enums (5)

  1. Si el Color es algo específico para solo Car , entonces esa es la forma en que limitaría su alcance. Si va a tener otra Enum de Color que usen otras clases, entonces también podría hacerlo global (o al menos fuera de Car ).

  2. No hace ninguna diferencia. Si hay uno global, el local se sigue utilizando de todos modos, ya que está más cerca del alcance actual. Tenga en cuenta que si define esas funciones fuera de la definición de clase, necesitará especificar explícitamente Car::Color en la interfaz de la función.

En el siguiente fragmento de código, la Enum de Color se declara dentro de la clase Car para limitar el alcance de la enumeración e intentar no "contaminar" el espacio de nombres 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) ¿Es esta una buena manera de limitar el alcance de la enumeración de Color ? O, ¿debería declararlo fuera de la clase Car , pero posiblemente dentro de su propio espacio de nombres o estructura? Acabo de encontrar este artículo hoy, que defiende lo último y analiza algunos aspectos interesantes sobre las enumeraciones: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums .

(2) En este ejemplo, cuando se trabaja dentro de la clase, ¿es mejor codificar la enumeración como Car::Color o bastará con Color ? (Supongo que el primero es mejor, en caso de que haya otra Enum de Color declarada en el espacio de nombres global. De esa forma, al menos, somos explícitos sobre la enumeración a la que nos referimos).


En general, siempre pongo mis enums en una struct . He visto varias pautas que incluyen "prefixing".

enum Color { Clr_Red, Clr_Yellow, Clr_Blue, };

Siempre pensé que esto se parecía más a las pautas de C++ que a las de C++ (por ejemplo, debido a la abreviación y también a los espacios de nombres en C++ ).

Entonces, para limitar el alcance, ahora tenemos dos alternativas:

  • espacios de nombres
  • estructuras / clases

Personalmente tiendo a usar una struct porque puede usarse como parámetros para la programación de plantillas, mientras que un espacio de nombres no puede ser manipulado.

Los ejemplos de manipulación incluyen:

template <class T> size_t number() { /**/ }

que devuelve la cantidad de elementos de enum dentro de la estructura T :)


Hoy en día, usando C ++ 11, puedes usar la clase enum para esto:

enum class Color { RED, BLUE, WHITE };

AFAII esto hace exactamente lo que quieres.


Prefiero el siguiente enfoque (código a continuación). Resuelve el problema de "contaminación del espacio de nombres", pero también es mucho más seguro (no puede asignar e incluso comparar dos enumeraciones diferentes, o su enumeración con otros tipos incorporados, etc.).

struct Color { enum Type { Red, Green, Black }; Type t_; Color(Type t) : t_(t) {} operator Type () const {return t_;} private: //prevent automatic conversion for any other built-in types such as bool, int, etc template<typename T> operator T () const; };

Uso:

Color c = Color::Red; switch(c) { case Color::Red: //некоторый код break; } Color2 c2 = Color2::Green; c2 = c; //error c2 = 3; //error if (c2 == Color::Red ) {} //error If (c2) {} error

Creé macro para facilitar el uso:

#define DEFINE_SIMPLE_ENUM(EnumName, seq) / struct EnumName {/ enum type / { / BOOST_PP_SEQ_FOR_EACH_I(DEFINE_SIMPLE_ENUM_VAL, EnumName, seq)/ }; / type v; / EnumName(type v) : v(v) {} / operator type() const {return v;} / private: / template<typename T> / operator T () const;};/ #define DEFINE_SIMPLE_ENUM_VAL(r, data, i, record) / BOOST_PP_TUPLE_ELEM(2, 0, record) = BOOST_PP_TUPLE_ELEM(2, 1, record),

Uso:

DEFINE_SIMPLE_ENUM(Color, ((Red, 1)) ((Green, 3)) )

Algunas referencias útiles:

  1. Herb Sutter, Jum Hyslop, C / C ++ Users Journal, 22 (5), mayo de 2004
  2. Herb Sutter, David E. Miller, Bjarne Stroustrup Enumerados fuertemente tipados (revisión 3), julio de 2007

Si está creando una biblioteca de códigos, entonces usaría el espacio de nombres. Sin embargo, solo puede tener una Enumeración de color dentro de ese espacio de nombres. Si necesita una enumeración que podría usar un nombre común, pero podría tener constantes diferentes para diferentes clases, use su enfoque.