¿Por qué las personas usan enumeraciones en C++ como constantes cuando pueden usar const
?¿Por qué las personas usan enumeraciones en C++ como constantes mientras pueden usar const?
Respuesta
Una enumeración implica un conjunto de relacionadas constantes, por lo que la información adicional sobre la relación debe ser útil en su modelo del problema en cuestión.
Hm, eso no se ve como una respuesta a la pregunta (aunque fue aceptado). Las personas usan enums donde podrían usar 'const' y los valores están ** no ** relacionados. A menudo verá 'enum {ALGO = 2232; } '(como eso; enum sin nombre con un solo valor) en lugar de' const int ALGO = 2232; '.Es porque enum nunca obtiene ningún almacenamiento mientras que la variable const sigue siendo una variable y obtendrá un almacenamiento (estático) si el compilador no puede demostrar que no va a necesitar uno, lo que a menudo no es posible. –
Otra razón es que las variables "const" POD son una característica más reciente de C++, y todavía existen muchas bases de códigos más antiguas (y programadores que prefieren la mayor compatibilidad). –
Una de las razones es que requiere más const
escribiendo:
enum { Val1, Val2, Val3 };
... ... frente
const int Val1=0, Val2=1, Val3=2;
No es la única razón. Además, no hay una gran diferencia al escribir. –
enumeraciones son tipos distintos, por lo que puede hacer las cosas orientadas de tipo similar a la sobrecarga con ellos:
enum Color { Red,Green,Blue };
enum Size { Big,Little };
void f(Color c) {
}
void f(Size s) {
}
int main() {
f(Red);
f(Big);
}
Esto no es lo que hizo la pregunta. La pregunta es: ¿por qué la gente escribe cosas como: enum {Margin = 50}; – Claudio
Hay una razón histórica también cuando se trata de una plantilla cumplida programacion 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 puede 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 un const int estática puede tener memoria reservada para ello en tiempo de ejecución, mientras que una enumeración nunca se va a tener una ubicación de memoria real reservada para él, y se repartirá en tiempo de compilación. Ver this related question.
Los mensajes son más descriptivos cuando se usan. Considere:
int f(int fg, int bg)
frente
int f(COLOR fg, COLOR bg)
Además, las enumeraciones dan un poco más de seguridad de tipos, porque
- enteros no son implícitamente convertible es posible enumerar los tipos
- enumeración de uno tipo no es implícitamente convertible en enumeración de otro tipo
Este es un hilo viejo, pero las dos declaraciones al final de esta respuesta son falsas y es necesario corregirlas. – motiz88
"los enteros no son implícitamente convertibles en tipos enum" y "enum de un tipo no es implícitamente convertible a enum de otro tipo" - falso. Normal 'enum's convertirá silenciosamente a/desde enteros, en C++ como en C. Así que estrictamente _no_ proporcionan esta seguridad. Sin embargo, en C++ 11, hay 'enum class' que es un estilo de C++ apropiado" re-imaginando "de' enum': las conversiones implícitas se han ido, y además los nombres de los valores siempre deben ser calificados. Esto es similar a C# 'enum's, y evita los problemas de contaminación de nombre/colisión de nombres que surgen con el antiguo' enum' de C. – motiz88
@ motiz88 - Creo que puede estar confundido en este caso. Pruebe este código en gcc (deberá reformatearlo usted mismo): int main() {enum MyEnum1 {VAL11, VAL12, VAL13}; enum MyEnum2 {VAL21, VAL22, VAL23, VAL24}; int int1 = VAL11; MyEnum1 enum1 = 3; MyEnum2 enum2 = VAL11; enum2 = enum1; int int2 = enum1; return 0; } Los valores Enum se convierten implícitamente en enteros, pero no al revés, y los "tipos enum" no se convierten implícitamente entre sí. En principio, creo que Ask es correcto aquí, pero no creo que sea una respuesta a la pregunta de la operación. – cosimo193
enumeraciones también se puede utilizar 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
{
...
}
frente:
int const baz = 0;
int const meh = 1;
void foo (int bar) // what are valid values for bar?
{
...
}
'typedef int my_new_fangled_type; void foo (my_new_fangled_type bar); 'Problema resuelto, no se necesita ninguna enumeración, y puedo cambiar la representación de la memoria reemplazando' typedef int' con 'typedef uchar' o algo así. :) – weberc2
Usando una enumeración documenta las opciones válidas de una manera concisa y permite que el compilador para hacerlas cumplir.
Si están usando las constantes globales de Enum Store, como Pi, por ejemplo, entonces no sé cuál es su objetivo.
enum es un tipo integral, no creo que pueda almacenar una constante como Pi sin pérdida significativa de precisión :) – ASk
pueden almacenar 314159 y simplemente div por 10^5 cada vez: P con suerte el ejemplo da el idea correcta sobre lo que quiero decir con constantes globales, sin embargo. – dss539
me gusta el comportamiento automático que puede ser utilizado con enumeraciones, por ejemplo:
enum {NONE, START, HEY, HO, LAST};
Entonces es fácil de bucle hasta el pasado, y cuando se añade un nuevo estado (o lo que está representado), el 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 bucle se adapta ...
A menos que alguien agregue accidentalmente el nuevo literal enum al final de la lista, o decida dar valores no contiguos a los literales (por ejemplo, enum {} NONE = 0, START = 4, HEY = 7 etc ...). – cosimo193
Antes de fabricantes de compiladores implementaron el 14882 ISO/IEC: 1998 estándar C++, este código para definir una constante en un alcance de clase resultó en un error de compilación:
class Foo {
static const int MAX_LEN = 80;
...
};
Si la constante es un tipo de entero, un trabajo complejo es d efinir en una enumeración dentro de la clase:
class Foo {
enum {
MAX_LEN = 80
};
...
};
Las constantes no estáticas no se pueden inicializar de esa manera. Creo que querías decir "static const int Val1". Además, existen inconvenientes en el uso de este método de inicialización en clase: no se garantiza la creación del símbolo de Val1. – ASk
@ASk: El problema es que el símbolo para "static const int Val1" no se garantiza que ** no ** se genere, por lo que el programador usa enum en su lugar, porque eso no crea ningún símbolo en absoluto. –
Bruce Eckel da una razón en Thinking in C++:
In older versions of C++,
static const
was not supported inside classes. This meant thatconst
was useless for constant expressions inside classes. However, people still wanted to do this so a typical solution (usually referred to as the “enum hack”) was to use an untaggedenum
with no instances. An enumeration must have all its values established at compile time, it’s local to the class, and its values are available for constant expressions. Thus, you will commonly see:#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 para vincular el sitio de Bruce Eckel : http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html.
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
.
Es en parte porque los compiladores de más edad no apoyaron la declaración de una verdadera constante
class C
{
const int ARealConstant = 10;
};
clase así que tuvimos que hacer esto
class C
{
enum { ARealConstant = 10 };
};
Por esta razón, muchas bibliotecas portátiles seguir utilizando este formulario .
La otra razón es que las enumeraciones se pueden utilizar como un dispositivo sintáctica conveniente de organizar constantes de clase en los que están relacionados, y los que no son
class DirectorySearcher
{
enum options
{
showFiles = 0x01,
showDirectories = 0x02,
showLinks = 0x04,
};
};
vs
class Integer
{
enum { treatAsNumeric = true };
enum { treatAsIntegral = true };
enum { treatAsString = false };
};
- 1. pixel.gif, ¿por qué las personas lo usan?
- 2. Razones para usar las constantes de NSString sobre las enumeraciones
- 3. ¿Por qué las personas usan jQuery para operaciones básicas?
- 4. Enumeraciones y constantes. ¿Qué usar cuando?
- 5. ¿Por qué las personas usan linq en sql?
- 6. ¿por qué usar constantes de cadena frente a constantes enum?
- 7. ¿Por qué las personas usan Puppet/Chef con Amazon Cloud Formation en lugar de usar CloudInit?
- 8. ¿Por qué las personas usan ATL para la programación COM?
- 9. ¿Por qué las enumeraciones no se pueden modificar?
- 10. ¿Por qué las enumeraciones de TypeLib no están expuestas como enumeraciones en Visual Basic 6.0?
- 11. ¿Por qué C# limita el conjunto de tipos que se pueden declarar como const?
- 12. ¿Se pueden usar constantes estáticas en PHP?
- 13. ¿Por qué algunas personas usan "Ninguno" como miembro de la enumeración?
- 14. ¿Por qué las personas usan __ (doble guión bajo) tanto en C++
- 15. ¿Qué técnicas/estrategias usan las personas para construir objetos en C (no en C++)?
- 16. ¿Por qué las personas usan Command-line en lugar de IDE?
- 17. ¿Por qué usar constantes en la programación?
- 18. ¿Por qué las personas usan valores de magia en lugar de nulo en su código?
- 19. ¿Por qué usar constantes hexadecimales?
- 20. ¿Se pueden fusionar las enumeraciones de Java (como Bitwise en C#)?
- 21. Pthread: ¿Por qué las personas se molestan en utilizar pthread_exit?
- 22. ¿Por qué las constantes indefinidas se evalúan como verdaderas?
- 23. HTML5: ¿Por qué las personas no usan "ContentEditable" para sus sitios web Comentario de entrada?
- 24. ¿Por qué las personas usan la expresión regular para el correo electrónico y otras validaciones complejas?
- 25. ¿Por qué los nulables no pueden declararse const?
- 26. Enumeraciones de Java vs. constantes estáticas
- 27. ¿Por qué las matrices const de Pascal no son en realidad constantes?
- 28. ¿Por qué las personas siempre usan la reasignación de variables de instancia en Objective-C (es decir, iPhone)?
- 29. miembros const estáticos Por qué no pueden aparecer en una expresión constante como 'interruptor'
- 30. Objetivo C - ¿Por qué las constantes comienzan con k
sé que esto es un hilo muy antiguo, pero ¿podrías dar un ejemplo? Cuando leí esta pregunta, estaba pensando en las líneas de código que devuelve un int de una función, pero usa una enumeración para definir 'versiones' específicas del valor de retorno, p. condición de error, tiempo de espera, etc. Algunas de las respuestas a continuación parecen abordar problemas totalmente diferentes a eso. En mi opinión, es incorrecto usar una enumeración de esa manera a menos que, como dicen las personas, tu compilador tenga una funcionalidad limitada wrt estática. – cosimo193
Posible duplicado de [¿Debo usar #define, enum o const?] (Https://stackoverflow.com/questions/112433/should-i-use-define-enum-or-const) –