The problem: representing series of values
It is very common to have a series of values that need to be
represented. For example, to simulate a traffic light requires
representing three values (red, yellow, and green),
but there is no built-in C++ color datatype.
Use integer values to represent
colors, for example red as 0, yellow as 1, and green as 2.
There is nothing "green" about the value 2, and it could just as easily
be represented by some other number. However, it is common to start
a series at zero and continue up by ones.
The danger of magic numbers
Use of these "magic" numbers in the source code makes the code unreadable.
For example,
x = 1;
What does this do, assign the number one or the color yellow to x?
Use of numbers is also very error prone - it is easy
to mistakenly use the wrong one and making changes to the numbers
and making updates to all references is difficult.
Use names instead of numbers
A better solution is to create named constants for each of the
values. By convention, these named constants are uppercase.
const int RED = 0;
const int YELLOW = 1;
const int GREEN = 2;
Now it's easy to distinguish between assignment of the number 1 and the color yellow.
int y;
int x;
. . .
y = 1; // assigns the integer one
x = YELLOW; // assigns yellow (which happens to be 1).
There is still the problem that we declare x as an int altho
it's a color.
The enum type declaration provides a solution
C++ uses the enum
statement to assign sequential
integer values to names
and provide a type name for declaration.
enum TrafficLightColor {RED, YELLOW, GREEN};
. . .
int y;
TrafficLightColor x;
. . .
y = 1;
x = YELLOW;
The enum declaration creates a new integer type.
By convention the first letter of an enum type should
be in uppercase. The list of values follows, where the
first name is assigned zero, the second 1, etc.
Type checking prevents some erroneous assignments
The compiler may issue an error message or warning
if you try to assign one kind of enum to a different kind.
It also allows some dangerous types of assignments.
enum TrafficLightColor {RED, YELLOW, GREEN};
enum Gender {MALE, FEMALE};
TrafficLightColor x;
int i;
. . .
x = YELLOW; // good
i = x; // Legal, but bad style. Assigns the integer representation.
i = (int)x; // As above, explicit casting is better style.
x = (TrafficLightColor)2; // Legal, but very dangerous. No checking.
x = FEMALE; // BAD, Compiler may give error or warning.
x = 5; // BAD, Compiler may give error or warning.
Related pages
Enum Values and I/O.