O que são enums e como utilizá-los melhor em 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 enum
s:
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 enum
s 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 enum
s 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 enum
s diferentes que representam coisas diferentes mas que podem ter a mesma constante. Como?
A resposta é namespace
s!
Em C++ podemos declarar nossos enum
s dentro de namespace
s 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; [/code] É isso aí galera, até a próxima.
“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
31 de May de 2009 at 20:50
Hehehe, é isso aí!
Perseverança!
Murilo Adriano
15 de June de 2009 at 23:25
Ótimo artigo, muito obrigado.
Anonimo
25 de July de 2009 at 18:41
[…] com um comentário Mais uma trick com enums. […]
Sobrecarga do operator++ para enums « Murilo :P
26 de July de 2009 at 00:37
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
19 de September de 2009 at 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
23 de September de 2009 at 09:24
Muito bom artigo, obrigado por compartilhar, me ajudou muito!
Yuri Souza Padua
15 de October de 2009 at 02:41
[…] Fonte [Murilo ] […]
[C++] Basico sobre: Enum « Computação & Coisas Nerds (by Andreo Vieira)
21 de May de 2010 at 16:06
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
6 de January de 2011 at 13:01
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
28 de March de 2011 at 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
28 de March de 2011 at 20:14
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
29 de March de 2011 at 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
29 de March de 2011 at 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 ooperator int()
que é o operador que é chamado quando você faz uma conversão paraint
(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
30 de March de 2011 at 08:37
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
10 de September de 2011 at 17:14
Muito bom, tirei minha duvida.
Renato Santos
24 de March de 2013 at 12:24