Eddig többnyire számokkal és stringekkel foglalkoztunk. A valós világ modellezéséhez néha csak néhány olyan értékre van szükségünk, amit egy változó felvehet. Előfordulhat, hogy szeretnél egy külön típust, amelynek csak néhány, egymástól különböző nevű értéke lehet. Például egy gördeszkagyárban a deszka anyaga csak maple, bamboo vagy plastic lehet.
Ezeket az értékeket egész számokkal is kódolhatnád, de külön kódot kellene írnod annak ellenőrzésére, hogy nem érkezik-e a rendszertől érvénytelen érték a deszka anyagához.
Ezeknek a mágikus számoknak a jelentését nehéz visszakövetni a forráskódban, és könnyen összekeverhetők.
Az enumerations használatával kifejezőbb kódot írhatsz, és elkerülheted a véletlen összehasonlítási hibákat.
Az ilyen típusú felsorolás pontos neve scoped enumeration.
Az alábbi kódrészlet megmutatja, hogyan definiálj egy DeckMaterial enumeration-t.
Figyeld meg az enum class kulcsszót és a definíció végén álló ;-t:
enum class DeckMaterial {
maple,
bamboo,
plastic
};
Most nézd meg a gördeszkabolt árazó függvényét, és figyeld meg a hatókörfeloldó operátort (::), amellyel megadod, hogy az enumerator melyik enumeration-höz tartozik:
double deck_price(double base_price, DeckMaterial material) {
if(material == DeckMaterial::plastic) {
return base_price * 0.9;
}
return base_price * 1.3;
}
Képzeld el, hogy van egy második enumeration-öd a kerék anyagához:
enum class WheelMaterial {
steel,
clay,
plastic
};
Bár a kerekek és a deszka is lehet plastic, a kettő mégsem keverhető össze.
Két különböző típusról van szó: a DeckMaterial plastic és a WheelMaterial plastic.
Minden enumeration a saját scope-jában, a saját namespace-ében tárolja az enumerator-jait.
Ezért is hívják őket scoped enumerations-nek.
Talán arra gondolsz, hogy ha van egy olyan név, mint a scoped, akkor unscoped felsorolások is léteznek, és ebben igazad lenne.
Az Unscoped enumerations egyre népszerűtlenebbek, mert mindannyian ugyanazt a globális névteret használják.
Az osztozás miatt nem lehet két unscoped enumerations ugyanazokkal az enumerators-okkal, mint amilyen a fenti példában a plastic.
Ráadásul az unscoped enumerations implicit módon egész számokká alakulnak.
Nézd meg az alábbi példát, amely meglepő eredményt mutat:
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!
Ha a scoped enumerations-t egész számokká szeretnéd alakítani, használhatod a static_cast<int>-et.