Última atualização:2026-10-12
Tipos de enumeração (enum) em C++¶
Sobre o autor:¶
Conta oficial do WeChat:

Comportamento tradicional¶
As enumerações têm os seguintes problemas:
- O escopo é ilimitado, o que facilita conflitos de nomenclatura. Por exemplo, o código a seguir não compila:
enum Color
{
RED,
BLUE
};
enum Feeling
{
EXCITED,
BLUE
};
int main()
{
Color a = BLUE; // error
Feeling b = EXCITED;
std::cout << a << ":" << b << std::endl;
return 0;
}
A implementação concreta está em: tradition_color.cpp
Prática clássica¶
Uma forma simples de resolver os conflitos de nomenclatura causados pelo escopo ilimitado é adicionar um prefixo ao nomear as variáveis de enumeração, como no exemplo acima, alterando para COLOR_BLUE e FEELING_BLUE.
Em geral, por consistência, adicionamos o prefixo a todas as constantes. Mas, assim, o código que define as variáveis de enumeração fica prolixo. Em programas C, talvez seja inevitável fazer assim; programadores C++, porém, dificilmente apreciam esse método. A alternativa são os namespaces:
Depois disso, é possível definir uma nova variável de enumeração com Color::Type c = Color::RED;. Se for usado using namespace Color, o prefixo pode até ser omitido, simplificando o código. No entanto, como um namespace pode ser estendido posteriormente com novos conteúdos, o fechamento de escopo que ele oferece não é alto. Em projetos grandes, ainda é possível que pessoas diferentes dêem o mesmo nome de tipo de enumeração a coisas diferentes.
A forma mais "eficaz" é usar uma classe ou estrutura para restringir o escopo: por exemplo, o método para definir novas variáveis é o mesmo do namespace acima; a diferença é que assim não precisamos nos preocupar com a classe sendo modificada em outro lugar. Usa-se uma estrutura, e não uma classe, porque justamente se espera que essas constantes sejam publicamente acessíveis.
A implementação concreta está em: classic_practice.cpp
As enum classes do C++11¶
A abordagem acima resolve o primeiro problema, mas continua impotente diante dos outros dois. Felizmente, o padrão C++11 introduziu as "enum classes" (enum class), que resolvem bem os problemas mencionados.
- O escopo do novo enum deixa de ser global
- Não há conversão implícita para outros tipos
/**
* @brief C++11的枚举类
* 下面等价于enum class Color2:int
*/
enum class Color2
{
RED=2,
YELLOW,
BLUE
};
Color2 c2 = Color2::RED;
cout << static_cast<int>(c2) << endl; //必须转!
- É possível especificar um tipo específico para armazenar o enum
enum class Color3:char; // 前向声明
// 定义
enum class Color3:char
{
RED='r',
BLUE
};
char c3 = static_cast<char>(Color3::RED);
A implementação concreta está em: classic_practice.cpp
Tipos de enumeração dentro de classes¶
Às vezes queremos que certas constantes sejam válidas apenas dentro da classe. Como as constantes de macro definidas por #define são globais e não atendem ao objetivo, pensamos em usar const para modificar membros de dados. De fato, os membros de dados const existem, mas seu significado não é o que esperamos.
Um membro de dados const é constante apenas durante o tempo de vida de um objeto; para a classe inteira, ele é variável, porque a classe pode criar vários objetos, e o valor do membro de dados const pode ser diferente em objetos diferentes.
Não é possível inicializar um membro de dados const na declaração da classe. O uso a seguir está errado, porque, enquanto o objeto da classe não for criado, o compilador não sabe qual é o valor de SIZE. (antes do padrão C++11)
O correto é fazê-lo na lista de inicialização do construtor da classe:
class A
{
A(int size); // 构造函数
const int SIZE ;
};
A::A(int size) : SIZE(size) // 构造函数的定义
{
}
A a(100); // 对象 a 的 SIZE 值为 100
A b(200); // 对象 b 的 SIZE 值为 200
Como estabelecer, então, uma constante fixa em toda a classe?
Não conte com membros de dados const; use constantes de enumeração dentro da classe. Por exemplo:
class Person{
public:
typedef enum {
BOY = 0,
GIRL
}SexType;
};
//访问的时候通过,Person::BOY或者Person::GIRL来进行访问。
As constantes de enumeração não ocupam espaço de armazenamento dos objetos; elas são todas avaliadas em tempo de compilação.
A desvantagem das constantes de enumeração é que seu tipo de dados implícito é o inteiro, com valor máximo limitado e sem capacidade de representar números de ponto flutuante.
Tópicos relacionados¶
- Funções virtuais puras e classes abstratas em C++ | C++那些事
- Asserções com assert em C++ | C++那些事
- Bit fields em C++ | C++那些事
- Implementando polimorfismo de C++ em linguagem C | C++那些事
- Constantes e modificadores com const em C++ | C++那些事
- A família completa do const em C++ | C++那些事
- O operador de desreferência * em C++ | C++那些事
- Inicialização e atribuição em C++ | C++那些事
- Formas de retornar múltiplos valores em C++ | C++那些事
- A palavra-chave mutable em C++ | C++那些事