[ fromfile: enums.xml id: enums ]
In Chapter 2, "Top of the class
", we discussed at some length how you can add new types to the C++ language by defining classes.
Another way to add new types to C++ deserves some more discussion.
The keyword enum
is used for assigning integral values to C++ identifiers.
For example, when designing data structures that perform bitwise operations, it is convenient to give names to the various bitmasks.
Qt frequently uses enums for this.
A good example can be seen in QFileDialog::Option
.
The main purpose for an enum
is to make the code more readable and, hence, easier to maintain.
For example:
enum {UNKNOWN, JAN, FEB, MAR };
defines three constant identifiers, numbered in ascending order, starting at 0. It is equivalent to
enum {UNKNOWN=0, JAN=1, FEB=2, MAR=3};
The identifiers, JAN
, FEB
, and MAR
are called enumerators.
They can be defined and initialized to arbitrary integer values.
Because enumerators are const
items, their names are frequently spelled with uppercase letters. (Although Qt does not follow this convention.)
enum Ages {MANNY = 10, MOE, JACK = 23, SCOOTER = JACK + 10};
If the first enumerator, MANNY
, had not been initialized, it would automatically get the value 0
.
Because MANNY
has been initialized to 10
and MOE
was not assigned a value, the value of MOE
is 11
.
The values of enumerators need not be distinct.
Assigning a name to an enum
defines a new type.
For example:
enum Winter {JAN=1, FEB, MAR, MARCH = MAR };
The name Winter
is called a tag name.
Now, it is possible to declare variables of type Winter
.
Winter m = JAN; int i = JAN; // OK - enum can be implicitly converted to int. m = i; // error - explicit cast is required. m = static_cast<Winter>(i); // OK i = m; // OK m = 4; // error
The tag name and the enumerators must be distinct identifiers within their scope.
Enumerations can be implicitly converted to ordinary integer types, but the reverse is not possible without an explicit cast.
Example 19.3 demonstrates the use of enum
and also shows how enumerators look when they are printed out.
Example 19.3. src/enums/enumtst.cpp
#include <iostream> using namespace std; int main(int, char** ) { enum Signal { off, on } sig; sig = on; enum Answer { no, yes, maybe = -1 }; Answer ans = no; // enum Neg {no,false} c; enum { lazy, hazy, crazy } why; int i, j = on; sig = off; i = ans; // ans = s ans = static_cast<Answer>(sig); ans = (sig ? no : yes); sig = static_cast<Signal>(9); Signal sig2(sig); why = hazy; cout << "sig2, ans, i, j, why " << sig2 << ans << i << j << why << endl; return 0; } Output: src/enums> ./enums sig2, ans, i, j, why 91011 src/enums>
A new type, 2 new enum identifiers, and a variable definition all in one line. | |
Just the type/enum definitions. | |
An instance of an enum. | |
Illegal redefinitions of identifiers. | |
An unnamed enum variable. | |
An enum can always convert to int. | |
Conversions between enum types cannot be done implicitly. | |
Conversion is okay with a cast. | |
Bad news! | |
Have we added an unnamed enumerator? |
<include src="src/enums/enumtst.cpp" href="src/enums/enumtst.cpp" id="enumtstcpp" mode="cpp"/>
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |