Another common data requirement we will soon run in to is a desire to have a property be one of a limited set of values.
We've seen booleans
for capturing one of two states - true
or false
, but what if we want a property to be one of a number of possibilities?
We could imagine a need to store a character's faction, for example, with possible values being "Human", "Elf", and "Undead"
This is where the enum
comes in:
enum class Faction {
Human,
Elf,
Undead
}
How can we create an enum called Hostility
?
Variables that store one of these values will have a type of Faction
, and we can access the options using the scope resolution operator ::
. This is shown in the below examples:
Faction PlayerFaction { Faction::Human };
bool isElf(Faction SelectedFaction) {
return SelectedFaction == Faction::Elf;
}
class Vampire {
public:
Faction GetFaction() { return Faction };
private:
Faction Faction { Faction::Undead }
}
Vampire Enemy;
Faction EnemyFaction { Enemy.GetFaction() };
How can use our Hostility
enum to add a variable to this class on line 4?
1enum class Hostility { Friendly, Neutral, Hostile };
2
3class Character {
4 // ?
5};
6
using
Statements with EnumsIn some files, we may want to use the same enum over and over again, and the constant qualification of MyEnumName::
would make our code excessively verbose.
We can solve this problem in the same we we tacked the equivalent issue with namespaces - by adding a using
statement.
This can take our code from something like this:
enum class Faction { Human, Elf, Undead };
Faction MyFaction { Faction::Human };
To this:
enum class Faction { Human, Elf, Undead };
using enum Faction;
Faction MyFaction { Human };
Note, using enum
is a recent addition to the language, included as part of the C++ 20 spec that was published in 2021. It may not yet be supported by all compilers.
What statement can we add on line 3 above that will make line 6 work?
1enum class Hostility { Friendly, Neutral, Hostile };
2
3// ?
4
5class Character {
6 Hostility Hostility { Friendly };
7};
8
We could have captured these multiple-choice variables as some other type - for example, integers or strings.
But, if we use integers, our code becomes quite difficult to follow, as we have to remember what the numbers mean. For example, is 3
an elf or a dwarf?
Strings like "dwarf"
solve the readability problem. However, they consume more memory and network resources than an int
, and they're also slower to compare.
When our software asks a computer to compare two integers, for example, 3 == 3
, that can be done in a single operation.
Comparing strings is a bit more involved, as every character needs compared, one by one. A request like "dwarf" == "dwarf"
would require at least 5 operations - one for each character
Enums are fast to compare because, behind the scenes, they're just stored as integers by default.
The enum syntax is some compiler magic to let us solve this problem by attaching some semantic meaning to a collection of integers.
Enums combine the performance of integers with the readability of strings. Additionally, they have even more advantages:
enum
defines what the possible options are, our tools can be helpful. For example, our code editor will generally provide auto-complete support when we're working with enums.Become a software engineer with C++. Starting from the basics, we guide you step by step along the way