Por que as pessoas usam enums em C ++ como constantes, enquanto eles podem usar const?

StackOverflow https://stackoverflow.com/questions/899917

  •  23-08-2019
  •  | 
  •  

Pergunta

Por que as pessoas usam enums em C ++ como constantes quando eles podem usar const?

Foi útil?

Solução

Uma enumeração implica um conjunto de relacionadas constantes, assim que a informação adicional sobre o relacionamento deve ser útil em seu modelo do problema em questão.

Outras dicas

Bruce Eckel dá uma razão em Pensamento em C ++ :

Em versões mais antigas do C ++, static const não era suportado dentro das classes. Isto significava que const era inútil para expressões constantes dentro de classes. No entanto, as pessoas ainda queria fazer isso para uma solução típica (geralmente referido como o “enum hack”) era usar um enum não marcado com nenhuma instância. Uma enumeração deve ter todos os seus valores estabelecidos em tempo de compilação, é local para a classe, e seus valores estão disponíveis para expressões constantes. Assim, você normalmente 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;
}

[Edit]

Eu acho que seria mais justo para o site do ligação Bruce Eckel: http: // www .mindview.net / Livros / TICPP / ThinkingInCPP2e.html .

Enums são tipos distintos, para que possa fazer coisas orientadas para o tipo como sobrecarregar com eles:

enum Color { Red,Green,Blue };
enum Size { Big,Little };

void f( Color c ) {
}

void f( Size s ) {
}

int main() {
    f( Red );
    f( Big );
}

Há uma razão histórica muito quando se trata de modelo metaprogramming. Alguns compiladores poderia usar valores de um enum, mas não um int const estático para instanciar uma classe.

template <int N>
struct foo
{
    enum { Value = foo<N-1>::Value + N };
};

template <>
struct foo<0>
{
    enum { Value = 0; }
};

Agora você pode fazê-lo da maneira mais sensata:

template <int N>
struct foo
{
    static const int Value = foo<N-1>::Value + N;
};

template <>
struct foo<0>
{
    static const int Value = 0;
};

Outra possível razão é que um int const estático pode ter memória reservada para isso em tempo de execução, enquanto um enum nunca mais vai ter um local de memória real reservado para ela, e serão tratadas em tempo de compilação. Consulte esta pergunta relacionada.

Enums são mais descritivo quando usado. Considere o seguinte:

int f(int fg, int bg)

contra

 int f(COLOR fg, COLOR bg)

Além disso, enums dar um pouco mais tipo-segurança, porque

  • inteiros não são implicitamente conversível para tipos de enum
  • enum de um tipo não é implicitamente conversível para enum de outro tipo

Eu gosto do comportamento automático que pode ser usado com enums, por exemplo:

enum {NONE, START, HEY, HO, LAST};

Em seguida, ele é fácil de loop até LAST, e quando um novo estado (ou o que é representado) é adicionado, as adapta de lógica.

for (int i = NONE; i < LAST; i++)
{
    // Do stuff...
}

Adicione algo ...

enum {NONE, START, HEY, WEE, HO, LAST};

Os adapta laço ...

Antes de fornecedores do compilador implementou a ISO / IEC 14882: standard 1998, C ++, este código para definir uma constante em um escopo classe resultou em um erro de compilação:

class Foo {
    static const int MAX_LEN = 80;
    ...
};

Se a constante é um tipo inteiro, um trabalho kludgy redor é defini-lo em um enum dentro da classe:

class Foo {
    enum {
        MAX_LEN = 80
    };
    ...
};

enums também pode ser usado como um nome de tipo. Assim, você pode definir uma função que leva uma enumeração como um parâmetro, o que torna mais claro o que tipos de valores devem ser dado como argumentos para a função, em comparação a ter os valores definidos como variáveis ??const e a função aceitar apenas "int" como um argumento.

Considere o seguinte:

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
{
   ...
}

contra:

int const baz = 0;
int const meh = 1;

void foo (int bar) // what are valid values for bar?
{
   ...
}

Alguns depuradores irá mostrar o nome de enumeração em vez de seu valor quando a depuração. Isso pode ser muito útil. Eu sei que eu preferiria ver day_of_week = MONDAY que day_of_week = 1.

É em parte porque compiladores mais antigos não suportam a declaração de uma constante classe true

class C
{
  const int ARealConstant = 10;
};

então tive que fazer isso

class C
{
  enum { ARealConstant = 10 };
};

Por esta razão, muitas bibliotecas portáteis continuam a utilizar este formulário.

A outra razão é que enums pode ser usado como um dispositivo sintática conveniente para organizar as constantes de classe em aqueles que estão relacionados, e aqueles que não são

class DirectorySearcher
{
  enum options
  {
    showFiles = 0x01,
    showDirectories = 0x02,
    showLinks = 0x04,
  };
};

vs

class Integer
{
   enum { treatAsNumeric = true };
   enum { treatAsIntegral = true };
   enum { treatAsString = false };
};

Usando um documentos enum as opções válidas de forma concisa e permite que o compilador para aplicá-las.

Se eles estão usando lojas enum constantes globais, como Pi, por exemplo, então eu não sei o que seu objetivo é.

Uma razão é que const requer mais digitando:

enum { Val1, Val2, Val3 };

... contra ...

const int Val1=0, Val2=1, Val3=2;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top