Até agora, lidamos principalmente com números e strings. Para modelar o mundo real, muitas vezes queremos limitar os valores que uma variável pode assumir. Você pode querer um tipo dedicado, com alguns valores distintos e nomes distintos. Por exemplo, em uma fábrica de skates, o material do shape pode ser apenas maple, bamboo ou plastic.
Você poderia usar números inteiros para codificar esses valores, mas teria que escrever código extra para verificar se o sistema está enviando um valor inválido para o material.
O significado desses números mágicos é difícil de rastrear pelo código-fonte, e eles são fáceis de confundir.
As enumerations podem ser usadas para incentivar um código expressivo e para restringir comparações involuntárias.
O termo específico para esse tipo de enumeração é scoped enumeration.
O trecho abaixo mostra como escrever uma enumeration chamada DeckMaterial.
Repare na palavra-chave enum class e no ; no final da definição:
enum class DeckMaterial {
maple,
bamboo,
plastic
};
Agora, veja uma função de preços na loja de skates e repare no operador de resolução de escopo (::), que especifica um enumerator da enumeration:
double deck_price(double base_price, DeckMaterial material) {
if(material == DeckMaterial::plastic) {
return base_price * 0.9;
}
return base_price * 1.3;
}
Imagine que você tem uma segunda enumeration, para o material das rodas:
enum class WheelMaterial {
steel,
clay,
plastic
};
Embora as rodas e o shape possam ser feitos de plastic, os dois não podem ser confundidos.
Eles são tipos diferentes: DeckMaterial plastic e WheelMaterial plastic.
Cada enumeration terá seus enumerators no próprio escopo, no próprio namespace.
É por isso que elas são chamadas de scoped enumerations.
Você pode estar pensando que, com um nome como scoped, também existiriam enumerações unscoped, e você está certo.
As Unscoped enumerations estão ficando menos populares porque todas compartilham o mesmo namespace global.
Por causa desse compartilhamento, você não poderia ter duas unscoped enumerations com os mesmos enumerators, como plastic no exemplo acima.
Além disso, as unscoped enumerations são convertidas implicitamente em números inteiros.
Veja o exemplo abaixo para um resultado surpreendente:
enum CitrusFruits {
lemons, // 0
oranges, //1
};
enum IceCream {
walnut, // 0
apples, // 1
};
bool comparison{apples == oranges};
// => true
// Example from above:
bool comparison{DeckMaterial::plastic == WheelMaterial::plastic};
// => Does not compile!
Se você quiser converter scoped enumerations em números inteiros, pode usar static_cast<int>.