Murilo :P

C++, Computação, Programação, Web e afins :)

O que são enums e como utilizá-los melhor em C++

com 15 comentários

C++

O que são os enums (C e C++)

Um enum (enumeração) é um tipo definido pelo usuário (programador) que consiste em constantes do tipo int nomeadas.

Um jeito tradicional de se declarar constantes em C e C++ é o seguinte:

#define BRASIL 0
#define ITALIA 1
#define PORTUGAL 2
#define ALEMANHA 3

E eis a maneira de fazer o mesmo utilizando enums:

enum
{
        BRASIL,
        ITALIA,
        PORTUGAL,
        ALEMANHA
};

Pode-se, alternativamente, criar um tipo para seu enum:

enum Paises
{
        BRASIL,
        ITALIA,
        PORTUGAL,
        ALEMANHA
};

E declarar uma variável desse tipo com:

Paises pais; //C++ apenas
enum Paises pais; //C e C++

Num enum igual a esses acima, a primeira constante recebe o valor 0 e as subsequentes recebem o valor da constante anterior mais 1. Ou seja, BRASIL é 0, ITALIA é 1, PORTUGAL é 2 e ALEMANHA é 3.
Podemos também atribuir valores manualmente às constantes como em:

enum Paises
{
        BRASIL = 2,
        ITALIA,  //ITALIA é igual a 3 (2 + 1)
        PORTUGAL = 1,
        ALEMANHA  //ALEMANHA é igual a 2 (1 + 1)
};

Como podemos perceber no exemplo anterior, a mesma regra se aplica para os enums com valores manuais, o que não tiver um valor explicitamente inserido receberá o valor do anterior somado em 1. Percebemos também que podem haver constantes com o mesmo valor (BRASIL == ALEMANHA == 2).

Conversão

A conversão de uma constante de um enum para um inteiro por exemplo é feita automaticamente. Já o contrário não deve ser permitido pelo compilador.

enum Paises
{
        BRASIL,
        ARGENTINA,
        VENEZUELA
};

...

int inteiro = VENEZUELA + 2; //4
Paises pais = 3; //ERRO

Uma melhor maneira de usar enums em C++

Veja o exemplo:

enum Paises
{
        BRASIL,
        ITALIA,
        ALEMANHA
};

enum Uvas
{
        RUBI,
        ITALIA,
        UMOUTROTIPODEUVA
};

Isso irá ocasionar um erro porque ITALIA já foi definido. A saida do meu compilador (g++ 4.3.2) foi a seguinte:

murilo@blacksheep:~/$ g++ enums.cpp
enums.cpp:14: error: conflicting declaration ‘ITALIA’
enums.cpp:8: error: ‘
ITALIA’ has a previous declaration as ‘Paises ITALIA’

Mas e agora?? Eu quero ter dois enums diferentes que representam coisas diferentes mas que podem ter a mesma constante. Como?

A resposta é namespaces!
Em C++ podemos declarar nossos enums dentro de namespaces e assim termos as constantes em espaços de nomes diferentes. Nada de conflito agora hein g++!!!

namespace Paises
{
        enum
        {
                BRASIL,
                ITALIA,
                ALEMANHA
        };
}

namespace Uvas
{
        enum
        {
                RUBI,
                ITALIA,
                UMOUTROTIPODEUVA
        };
}

//*...*//
//Modo de uso:

std::cout << Uvas::ITALIA;
std::cout << Paises::ITALIA;

É isso aí galera, até a próxima.

Escrito por Murilo Adriano

sexta-feira 29 \29\UTC maio \29\UTC 2009 às 01:28

Publicado em C/C++, Programação

Etiquetado com , , ,

15 Respostas

Assinar os comentários com RSS.

  1. “Nada de conflito agora, ein g++!” kkkkkkk³
    Apesar de você já ter me explicado isso e eu já ter visto em um código que eu ajudei a desenvolver, não entendo bem.
    =x
    Mas, quem acredita sempre alcança, não é?
    Ainda irei entender.

    Eduardo

    domingo 31 \31\UTC maio \31\UTC 2009 em 20:50

  2. Hehehe, é isso aí!
    Perseverança!

    Murilo Adriano

    segunda-feira 15 \15\UTC junho \15\UTC 2009 em 23:25

  3. Ótimo artigo, muito obrigado.

    Anonimo

    sábado 25 \25\UTC julho \25\UTC 2009 em 18:41

  4. [...] com um comentário Mais uma trick com enums. [...]

    Sobrecarga do operator++ para enums « Murilo :P

    domingo 26 \26\UTC julho \26\UTC 2009 em 00:37

  5. Ainda há uma dúvida.

    Se eu tiver uma string em mãos, dentro de uma variavel qualquer, como posso saber se essa string pode ser ou não um dos elementos do meu Enum?

    Por exemplo:

    string s = “ITALIA”;

    Como saber se s pertence ao ENUM?

    Lucas

    sábado 19 \19\UTC setembro \19\UTC 2009 em 01:43

    • Opa Lucas, desculpe-me pela demora. Ando muito ocupado ultimamente.
      Enums são tipos enumerados numéricos, então não tem como comparar diretamente.
      O que você pode fazer é o seguinte:

      Você pode fazer algo como comparar o valor da string e obter o enum correspondente e trabalhar corretamente com esses enums.

      Abração Lucas, valeu!

      Murilo Adriano

      quarta-feira 23 \23\UTC setembro \23\UTC 2009 em 09:24

  6. Muito bom artigo, obrigado por compartilhar, me ajudou muito!

    Yuri Souza Padua

    quinta-feira 15 \15\UTC outubro \15\UTC 2009 em 02:41

  7. [...] Fonte [Murilo ] [...]

  8. Seria uma boa voce por ai um switch case usando os enuns… até eu saber que o trem era mais usado em ‘cases’ foi um parto kk

    Lucas P. Caixeta

    quinta-feira 6 \06\UTC janeiro \06\UTC 2011 em 13:01

  9. Um enum pode ter mais de um valor? Em java, por exemplo, pode-se ter:

    enum Pais {
    BRASIL(1, “Brasil”), ITALIA (2, “Itália”);
    private int codigo;
    private String nome;
    public Pais(int codigo, String nome) { this.codigo = codigo; this.nome = nome; }
    }

    Qual a alternativa em C++?

    Otto

    segunda-feira 28 \28\UTC março \28\UTC 2011 em 19:56

    • Olá Otto, podemos simular o comportamento criando uma classe como a seguinte:


      class Pais {
      public:
      // definidos depois
      static const Pais BRASIL;
      static const Pais ITALIA;
      // ...

      private:
      int codigo;
      std::string nome;

      private: // pode ser public se quiser que o usuário possa instanciar essa classe para outros objetos
      Pais(int codigo, std::string nome) {
      this->codigo = codigo;
      this->nome = mome;
      }

      public:
      // Propriedades e funções-membro
      };

      // Definições:
      const Pais Pais::BRASIL = Pais(1, "Brasil");
      const Pais Pais::ITALIA = Pais(2, "Itália");

      Se quiser ver mais ideias: http://stackoverflow.com/questions/1965249/how-to-write-java-like-enums-in-c

      Murilo Adriano

      segunda-feira 28 \28\UTC março \28\UTC 2011 em 20:14

  10. Fiz um enum igual ao seu Pais. E tenho o código (da lib UnitTest++):

    CHECK_EQUAL(Pais::BRASIL, paises.getPais(1)); // getPais retorna int.

    error: no matching function for call to ‘CheckEqual(UnitTest::TestResults&, Pais::, int, UnitTest::TestDetails)’

    O Pais::BRASIL não deveria ser convertido a int?

    Otto

    terça-feira 29 \29\UTC março \29\UTC 2011 em 19:54

    • Acho que o wordpress entendeu uma parte da mensagem de erro como se fosse HTML. Deveria ser Pais::(anonymous enum), com maior que/menor que no lugar dos parênteses.

      Otto

      terça-feira 29 \29\UTC março \29\UTC 2011 em 19:57

      • Nunca usei essa biblioteca de testes mas creio que basta você implementar os operator==. Recomendo que você implemente todos os operadores relacionais (>=, >, etc) se quiser algo bem próximo de um enum mesmo. Ainda recomendo que você implemente como abaixo o operator int() que é o operador que é chamado quando você faz uma conversão para int (um cast). Segue o código:

        public: // Na parte public da sua classe:
        operator int() const
        {
        return codigo;
        }

        bool operator==(int a) const
        {
        return codigo == a;
        }

        Qualquer coisa, estamos aí!

        Murilo Adriano

        quarta-feira 30 \30\UTC março \30\UTC 2011 em 08:37

  11. eu deixo um desafio, entrem na pagina
    http://www.dsc.ufcg.edu.br/~rangel/tp/downloads/Guia%20de%20Laboratorio%2001%202011.2%20T1.pdf.

    e tentem resolver o exercicio 2 que trata de enums, essa lista foi passada para os alunos de engenharia eletrica da UFCG.

    boa sorte

    Lucas

    sábado 10 \10\UTC setembro \10\UTC 2011 em 17:14


Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Sair / Alterar )

Imagem do Twitter

You are commenting using your Twitter account. Sair / Alterar )

Foto do Facebook

You are commenting using your Facebook account. Sair / Alterar )

Connecting to %s

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.