12.6. Enumerated Types

 < Free Open Study > 

An enumerated type is a type of data that allows each member of a class of objects to be described in English. Enumerated types are available in C++ and Visual Basic and are generally used when you know all the possible values of a variable and want to express them in words. Here are some examples of enumerated types in Visual Basic:

Visual Basic Examples of Enumerated Types
Public Enum Color    Color_Red    Color_Green    Color_Blue End Enum Public Enum Country    Country_China    Country_England    Country_France    Country_Germany    Country_India    Country_Japan    Country_Usa End Enum Public Enum Output    Output_Screen    Output_Printer    Output_File End Enum

Enumerated types are a powerful alternative to shopworn schemes in which you explicitly say, "1 stands for red, 2 stands for green, 3 stands for blue…." This ability suggests several guidelines for using enumerated types:

Use enumerated types for readability Instead of writing statements like

if chosenColor = 1

you can write more readable expressions like

if chosenColor = Color_Red

Anytime you see a numeric literal, ask whether it makes sense to replace it with an enumerated type.

Enumerated types are especially useful for defining routine parameters. Who knows what the parameters to this function call are?

C++ Examples of a Routine Call That Would be Better with Enumerated Types

int result = RetrievePayrollData( data, true, false, false, true );


In contrast, the parameters to this function call are more understandable:

C++ Examples of a Routine Call That Uses Enumerated Types for Readability
int result = RetrievePayrollData(    data,    EmploymentStatus_CurrentEmployee,    PayrollType_Salaried,    SavingsPlan_NoDeduction,    MedicalCoverage_IncludeDependents );

Use enumerated types for reliability With a few languages (Ada in particular), an enumerated type lets the compiler perform more thorough type checking than it can with integer values and constants. With named constants, the compiler has no way of knowing that the only legal values are Color_Red, Color_Green, and Color_Blue. The compiler won't object to statements like color = Country_England or country = Output_Printer. If you use an enumerated type, declaring a variable as Color, the compiler will allow the variable to be assigned only the values Color_Red, Color_Green, and Color_Blue.

Use enumerated types for modifiability Enumerated types make your code easy to modify. If you discover a flaw in your "1 stands for red, 2 stands for green, 3 stands for blue" scheme, you have to go through your code and change all the 1s, 2s, 3s, and so on. If you use an enumerated type, you can continue adding elements to the list just by putting them into the type definition and recompiling.

Use enumerated types as an alternative to boolean variables Often, a boolean variable isn't rich enough to express the meanings it needs to. For example, suppose you have a routine return true if it has successfully performed its task and False otherwise. Later you might find that you really have two kinds of False. The first kind means that the task failed and the effects are limited to the routine itself; the second kind means that the task failed and caused a fatal error that will need to be propagated to the rest of the program. In this case, an enumerated type with the values Status_Success, Status_Warning, and Status_FatalError would be more useful than a boolean with the values true and false. This scheme can easily be expanded to handle additional distinctions in the kinds of success or failure.

Check for invalid values When you test an enumerated type in an if or case statement, check for invalid values. Use the else clause in a case statement to trap invalid values:

Good Visual Basic Example of Checking for Invalid Values in an Enumerated Type
 Select Case screenColor   Case Color_Red      ...   Case Color_Blue      ...   Case Color_Green      ...   Case Else       <-- 1      DisplayInternalError( False, "Internal Error 752: Invalid color." ) End Select

(1)Here's the test for the invalid value.

Define the first and last entries of an enumeration for use as loop limits Defining the first and last elements in an enumeration to be Color_First, Color_Last, Country_First, Country_Last, and so on allows you to write a loop that loops through the elements of an enumeration. You set up the enumerated type by using explicit values, as shown here:

Visual Basic Example of Setting First and Last Values in an Enumerated Type
Public Enum Country    Country_First = 0    Country_China = 0    Country_England = 1    Country_France = 2    Country_Germany = 3    Country_India = 4    Country_Japan = 5    Country_Usa = 6    Country_Last = 6 End Enum

Now the Country_First and Country_Last values can be used as loop limits:

Good Visual Basic Example of Looping Through Elements in an Enumeration
' compute currency conversions from US currency to target currency Dim usaCurrencyConversionRate( Country_Last ) As Single Dim iCountry As Country For iCountry = Country_First To Country_Last   usaCurrencyConversionRate( iCountry ) = ConversionRate( Country_Usa, iCountry ) Next

Reserve the first entry in the enumerated type as invalid When you declare an enumerated type, reserve the first value as an invalid value. Many compilers assign the first element in an enumerated type to the value 0. Declaring the element that's mapped to 0 to be invalid helps to catch variables that were not properly initialized because they are more likely to be 0 than any other invalid value.

Here's how the Country declaration would look with that approach:

Visual Basic Example of Declaring the First Value in an Enumeration to Be Invalid
Public Enum Country    Country_InvalidFirst = 0    Country_First = 1    Country_China = 1    Country_England = 2    Country_France = 3    Country_Germany = 4    Country_India = 5    Country_Japan = 6    Country_Usa = 7    Country_Last = 7 End Enum

Define precisely how First and Last elements are to be used in the project coding standard, and use them consistently Using InvalidFirst, First, and Last elements in enumerations can make array declarations and loops more readable. But it has the potential to create confusion about whether the valid entries in the enumeration begin at 0 or 1 and whether the first and last elements of the enumeration are valid. If this technique is used, the project's coding standard should require that InvalidFirst, First, and Last elements be used consistently in all enumerations to reduce errors.

Beware of pitfalls of assigning explicit values to elements of an enumeration Some languages allow you to assign specific values to elements within an enumeration, as shown in this C++ example:

C++ Example of Explicitly Assigning Values to an Enumeration
enum Color {    Color_InvalidFirst = 0,    Color_First = 1,    Color_Red = 1,    Color_Green = 2,    Color_Blue = 4,    Color_Black = 8,    Color_Last = 8 };

In this example, if you declared a loop index of type Color and attempted to loop through Colors, you would loop through the invalid values of 3, 5, 6, and 7 as well as the valid values of 1, 2, 4, and 8.

If Your Language Doesn't Have Enumerated Types

If your language doesn't have enumerated types, you can simulate them with global variables or classes. For example, you could use these declarations in Java:

Java Example of Simulating Enumerated Types
// set up Country enumerated type class Country {    private Country() {}    public static final Country China = new Country();    public static final Country England = new Country();    public static final Country France = new Country();    public static final Country Germany = new Country();    public static final Country India = new Country();    public static final Country Japan = new Country(); } // set up Output enumerated type class Output {    private Output() {}    public static final Output Screen = new Output();    public static final Output Printer = new Output();    public static final Output File = new Output(); }

Cross-Reference

At the time I'm writing this, Java does not support enumerated types. By the time you read this, it probably will. This is a good example of the "rolling wave of technology" discussed in Section 4.3, "Your Location on the Technology Wave."


These enumerated types make your program more readable because you can use the public class members such as Country.England and Output.Screen instead of named constants. This particular method of creating enumerated types is also typesafe; because each type is declared as a class, the compiler will check for invalid assignments such as Output output = Country.England (Bloch 2001).

In languages that don't support classes, you can achieve the same basic effect through disciplined use of global variables for each of the elements of the enumeration.

 < Free Open Study > 


Code Complete
Code Complete: A Practical Handbook of Software Construction, Second Edition
ISBN: 0735619670
EAN: 2147483647
Year: 2003
Pages: 334

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