sirve - ¿Por qué las personas usan enumeraciones en C++ como constantes mientras pueden usar const?
para que sirve enum en c++ (12)
¿Por qué las personas usan enumeraciones en C ++ como constantes cuando pueden usar const
?
Algunos depuradores mostrarán el nombre de la enumeración en lugar de su valor al depurar. Esto puede ser muy útil. Sé que preferiría ver day_of_week = MONDAY
que day_of_week = 1
.
Antes de que los proveedores de compiladores implementaran el estándar ISO / IEC 14882: 1998 C ++, este código para definir una constante en un ámbito de clase daba como resultado un error de compilación:
class Foo {
static const int MAX_LEN = 80;
...
};
Si la constante es un tipo entero, un trabajo complejo es definirlo en una enumeración dentro de la clase:
class Foo {
enum {
MAX_LEN = 80
};
...
};
Bruce Eckel da una razón en Thinking in C ++ :
En versiones anteriores de C ++,
static const
no era compatible dentro de las clases. Esto significaba queconst
era inútil para expresiones constantes dentro de las clases. Sin embargo, las personas aún querían hacer esto, por lo que una solución típica (generalmente denominada "enum hack") era usar unaenum
no etiquetada sin instancias. Una enumeración debe tener todos sus valores establecidos en tiempo de compilación, es local para la clase y sus valores están disponibles para expresiones constantes. Por lo tanto, comúnmente verá:
#include <iostream> using namespace std; class Bunch { enum { size = 1000 }; int i[size]; }; int main() { cout << "sizeof(Bunch) = " << sizeof(Bunch) << ", sizeof(i[1000]) = " << sizeof(int[1000]) << endl; }
[Editar]
Creo que sería más justo vincular el sitio de Bruce Eckel: http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html .
El uso de un enum documenta las elecciones válidas de una manera concisa y permite que el compilador las haga cumplir.
Si están usando las constantes globales de Enum Store, como Pi, por ejemplo, entonces no sé cuál es su objetivo.
En parte se debe a que los compiladores antiguos no admitían la declaración de una constante de clase verdadera
class C
{
const int ARealConstant = 10;
};
así que tuve que hacer esto
class C
{
enum { ARealConstant = 10 };
};
Por este motivo, muchas bibliotecas portátiles continúan utilizando este formulario.
La otra razón es que las enumeraciones se pueden usar como un dispositivo sintáctico conveniente para organizar las constantes de clase en aquellas que están relacionadas, y las que no lo son
class DirectorySearcher
{
enum options
{
showFiles = 0x01,
showDirectories = 0x02,
showLinks = 0x04,
};
};
vs
class Integer
{
enum { treatAsNumeric = true };
enum { treatAsIntegral = true };
enum { treatAsString = false };
};
Los enumeraciones son tipos distintos, por lo que puedes hacer cosas orientadas a tipos como sobrecargarlas:
enum Color { Red,Green,Blue };
enum Size { Big,Little };
void f( Color c ) {
}
void f( Size s ) {
}
int main() {
f( Red );
f( Big );
}
Los mensajes son más descriptivos cuando se usan. Considerar:
int f(int fg, int bg)
versus
int f(COLOR fg, COLOR bg)
Además, las enumeraciones dan un poco más de seguridad de tipo, porque
- los enteros no son implícitamente convertibles a tipos enum
- enum de un tipo no es implícitamente convertible a enum de otro tipo
Me gusta el comportamiento automático que se puede usar con enumeraciones, por ejemplo:
enum {NONE, START, HEY, HO, LAST};
Luego es fácil repetir hasta LAST, y cuando se agrega un nuevo estado (o lo que se representa), la lógica se adapta.
for (int i = NONE; i < LAST; i++)
{
// Do stuff...
}
Añadir algo...
enum {NONE, START, HEY, WEE, HO, LAST};
El lazo se adapta ...
También hay un motivo histórico al tratar con la metaprogramación de plantillas. Algunos compiladores pueden usar valores de una enumeración, pero no una constante estática int para crear una instancia de una clase.
template <int N>
struct foo
{
enum { Value = foo<N-1>::Value + N };
};
template <>
struct foo<0>
{
enum { Value = 0; }
};
Ahora puedes hacerlo de la manera más sensata:
template <int N>
struct foo
{
static const int Value = foo<N-1>::Value + N;
};
template <>
struct foo<0>
{
static const int Value = 0;
};
Otra posible razón es que una constante estática int puede tener memoria reservada para ella en tiempo de ejecución, mientras que una enumeración nunca tendrá una ubicación de memoria real reservada para ella, y se tratará en tiempo de compilación. Vea esta pregunta relacionada.
Una enumeración implica un conjunto de constantes relacionadas , por lo que la información adicional sobre la relación debe ser útil en su modelo del problema en cuestión.
Una razón es que const
requiere más tipeo:
enum { Val1, Val2, Val3 };
...versus...
const int Val1=0, Val2=1, Val3=2;
las enumeraciones también se pueden usar como un nombre de tipo. De modo que puede definir una función que toma una enumeración como parámetro, lo que deja más claro qué tipos de valores se deben dar como argumentos a la función, en comparación con tener los valores definidos como variables const y la función que acepta simplemente "int" como un argumento
Considerar:
enum my_new_fangled_type {
baz = 0,
meh = 1
};
void foo (my_new_fangled_type bar) // bar can be a value listed in the enum
{
...
}
versus:
int const baz = 0;
int const meh = 1;
void foo (int bar) // what are valid values for bar?
{
...
}