Creating Enumerated Data Types With enum

 < Day Day Up > 



When programming, you will encounter many situations where code clarity can be improved by referring to integer values by a meaningful name rather that just the integer value itself. Enter the enumerated data type. An enumerated data type is a new type that you declare and assign possible integer value states that are referred to by name. Let us look at an example:

enum EyeColor {Black, Hazel, Blue, Brown};

This line of code declares a new data type called EyeColor that has four possible states: Black, Hazel, Blue, and Brown. The state names Black, Hazel, Blue, and Brown equate to the integer values 0, 1, 2, and 3 respectively. The type name EyeColor can now be used to declare a variable that can hold one of the four possible EyeColor state values:

EyeColor my_eye_color;

The variable my_eye_color can be assigned any one of the following values: Black, Hazel, Blue, or Brown. Observe the following line of code:

my_eye_color = Brown;

The nice thing about enum types is that the compiler will ensure you are only assigning one of the valid state values to the enum variable. For instance, the following line of code will produce a compiler error:

my_eye_color = 6; //Error...6 is an int not an EyeColor

Enums and Switch Statements

Enumerated types can be used with switch statements to improve their readability. Observe the following example:

Listing 10.5: switch statement

start example
 1  switch(my_eye_color){  2     case Brown: cout<<"You have brown eyes!"<<endl;  3                 break;  4     case Black: cout<<"You have black eyes!"<<endl;  5                 break;  6     case Hazel: cout<<"You have hazel eyes!"<<endl;  7                 break;  8     case Blue: cout<<"You have blue eyes!"<<endl;  9                 break; 10     default : cout<<"You have blue eyes!"<<endl; 11  }
end example

In this example, the value of my_eye_color is examined and the appropriate case statement is executed. The switch statement is rendered easier to read because the EyeColor state value names are used in each case statement. You no longer have to think in terms of 0, 1, 2, or 3. You are comparing the my_eye_color to Black, Hazel, Blue and Brown. As this switch statement shows, the order in which you perform the comparison is immaterial.

Changing an Enum’s Default State Values

The enum EyeColor’s states Black, Hazel, Blue, and Brown are assigned the integer values 0, 1, 2, and 3 by default. Since the name Black appears first in the list of possible states between the curly braces, its value is, by default, set to zero. The value of any enum state can be explicitly set in the following manner:

enum EyeColor {Black = 1, Hazel, Blue, Brown};

In this example, the EyeColor state Black has a value of 1. Each subsequent state will have the next integer value unless explicitly set in similar fashion. For instance, Hazel has the value 2, Blue has the value 3, and Brown has the value 4.

Although the values associated with the EyeColor enum states may not be important, there are cases where an enum’s state values might be a concern. Examine the following enum declaration:

enum BeveragePackage {Single = 1, SixPack = 6; TwelvePack = 12, EconoPack = 24};

In this example the enum BeveragePackage has four states, each with a non-default, non-consecutive value.

Enum State Name Conflicts

Two different enumerated types declared within the same namespace that contain one or more identical state names will cause a compiler error. Examine the following code:

enum EyeColor {Black, Hazel, Blue, Brown}; enum HairColor {Black, Blond, Red, Brown}; //error 

If these two enum declarations appeared in the same header file the compiler would generate an error because EyeColor has two states, Black and Brown, that also appear in HairColor. This can be fixed by changing the case of the first letter of either of the enum state names. For example, changing the state names in HairColor to begin with lowercase letters removes the conflict:

enum EyeColor {Black, Hazel, Blue, Brown}; enum HairColor {black, blond, red, brown}; //OK

Although this works, it is not the preferred resolution. I recommend instead putting each enum declaration in its own namespace as shown in the following example:

Listing 10.6: namespaces

start example
1  namespace EyeColor{ 2      enum EyeColor {Black, Hazel, Blue, Brown}; 3  } 4 5  namespace HairColor{ 6      enum HairColor {Black, Blond, Red, Brown}; 7  }
end example

Putting enum declarations in separate namespaces is like wrapping them in a cocoon. With each enum declaration in its own namespace the state names can safely begin with capital letters. To access each enum and state name, prefix each with its associated namespace using the scope resolution operator as shown in the following example:

HairColor::HairColor my_hair_color = HairColor::Black; EyeColor::EyeColor my_eye_color = EyeColor::Black;

Example 10.7 shows the switch statement of example 10.5 rewritten to use the EyeColor namespace:

Listing 10.7: switch statement

start example
 1  switch(my_eye_color){  2      case EyeColor::Brown: cout<<"You have brown eyes!"<<endl;  3                             break;  4      case EyeColor::Black: cout<<"You have black eyes!"<<endl;  5                             break;  6      case EyeColor::Hazel: cout<<"You have hazel eyes!"<<endl;  7                             break;  8      case EyeColor::Blue: cout<<"You have blue eyes!"<<endl;  9                             break; 10      default : cout<<"You have blue eyes!"<<endl; 11  }
end example

The Utility of name spaces

Namespaces are good places to put related declarations and attributes to prevent identifier name collisions with identical identifier names in the global namespace. The topic of namespaces will arise again in the study of structs and classes below.

Quick Summary

Typedefs let you create synonyms for existing data types. A typedef synonym is not a new type, just a nickname by which the typedefed name can be referenced. Typedefs can make your code easier to read and maintain. Enums are new types that can take on a range of integer values represented by names rather than numbers. When a variable of an enum type is declared, the compiler will check to ensure no other values are assigned to that variable other than those authorized. Enums can make your source code easier to read and help prevent programming errors by catching mistakes at compile time.



 < Day Day Up > 



C++ for Artists. The Art, Philosophy, and Science of Object-Oriented Programming
C++ For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504028
EAN: 2147483647
Year: 2003
Pages: 340
Authors: Rick Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net