Enumerated Data Types

Discussion in 'C++' started by Mridula, Feb 20, 2010.

  1. Mridula

    Mridula New Member

    Joined:
    Mar 5, 2008
    Messages:
    316
    Likes Received:
    19
    Trophy Points:
    0
    Occupation:
    S/w proffessional
    Location:
    Bangalore

    Introduction



    This article talks about Enumerated Data Types and set of guidelines in using them.

    Background



    Definition:

    An Enumerated Type is a user defined data type that maps set of names to numeric values called Enumerators. Enums are generally used when we know all the possible values of a variable and want to express them in our own meaningful words.

    Syntax:

    enum identifier
    {
    enumerator-list
    }


    Here identifier is often called as tag of the enumeration specified by the list.

    For Example:

    enum Colour
    {
    Colour_White,
    Colour_Yellow,
    Colour_Red,
    Colour_Green,
    Colour_Blue,
    }


    Notice that it does not include any fundamental data type in the declaration. We can say it creates a whole new data type from scratch without basing it on any other existing type.

    If we don't give any values to the enumeartors, by default here, 0 stands for Colour_White, 1 stands for Colour_Yellow etc.

    Characteristics:

    • An enumeration set can contain duplicate constant values. For example, you could associate the value 0 with two different identifiers in the same set.
    • The identifiers in the enumeration list must be distinct from other identifiers in the same scope with the same visibility, including ordinary variable names and identifiers in other enumeration lists.
    • Enumeration tags follow the normal scoping rules. They must be distinct from other enumeration, structure, and union tags with the same visibility.

    For Example:

    The code



    Code:
    #include<iostream.h>
    
    class A
    {
        public:
            
        enum Colour
        {
            colour_green=0,
            colour_peach=0,
            colour_white =1,
            colour_yellow =2            
        };
    
        //we cannot have color_green 2 times here
        /*enum Colour
        {
            colour_green=0,
            colour_peach=0,
            colour_white =1,
            colour_yellow =2,
            colour_green=3,
        };*/
    
        //We cannot have another variable of same type as in enum Colour
        //as below
        //int colour_yellow;
        
        //We cannot have colour_white as it already declared in enum Color
        /*enum MyColour
        {
            colour_red,
            colour_white
        };*/
    
        //We cannot have another Struct or Union of same type as below
        //in the same scope
        /*struct Colour
        {
            int red;
            int green;
        };*/
        
        
        void compare(Colour colour1, Colour colour2);
        
    };
    
    void A::compare(A::Colour colour1, A::Colour colour2)
    {
        if(colour1 == colour2)
        {
            cout<<"colour1 and colour2 are same\n";
        }
    }
    
    int main()
    {
        A a;
        a.compare(A::colour_green, A::colour_peach);
    
        return(0);
    }
    
    Output:
    
    ./a.out
    colour1 and colour2 are same
    
    Guidelines for using Enumerated Data Types

    1. Use Enum types for better Readability

    For Example;

    Instead of writing:

    if (mycolour == 2);

    We can better write it as:

    if (mycolour == colour_yellow)

    2. Use for Routine Paramters

    Calling Routines will be better with Enum types as below:

    Instead of calling a function :

    a.compare(2, 2);

    As shown in the above program it is better to call with Enum as below:

    a.compare(A::colour_green, A::colour_peach);

    3. Use Enum Types for Reliability

    An Enum type lets the compiler perform more thorough type checking than it can do with integers and named constants.

    For Example:

    If we have a named constant like:

    const int Wednesday = 3;

    And if we want to perform an assignement like:

    colour = Wednesday;

    This will not be a problem!!

    But if we have Colour as an Enum type and then declaring it's variable as colour. Now compiler will allow the colour variable to be assigned with only defined colours in the Enum. Otherwise it will throw an compiler error.

    4. Use Enum types for Maintainability

    Enum types for better to maintain the program. If our program does not use Enum and down the line if we find there is a flaw giving as - 0 stands for colour_green, 1 stands for colour_white and 2 stands for colour_yellow as values, then we have to go through our code and change where all 0s, 1s, 2s are used to whatever the value we want to change it.

    Instead, it is much easier now, since our program uses Enum, as it just needs the modification to the definition of Enum only. So we can change it to whatever the values we want and also we can do add some other colours to the enumerator list etc and just do re-compile it.

    5. Use Enum Types as an Alternative to bool type variables

    Many times, Boolean variable is not enough to express the meanings it needs to.

    For Example:

    We have a method, that returns True if it performs it's task successfully and it returns False otherwise.

    Down the line, if we want this method to Return 2 different types for False like:
    • First type means that the task failed and it's effects are limited to method itself.
    • Second type means the task failed and caused a fatal error and that needs to be propagated to rest of the Application.

    In this case, below Enum will be more meaningful and useful than having bool data type with True and False as return type of a method here.

    Enum Status
    {
    Status_Success,
    Status_Warning,
    Status_FatalError
    }


    6. Check for invalid values

    While testing an Enum type in an If or Case statement, check for invalid values.

    For Example:

    The code



    Code:
    #include<iostream.h>
    
    class A
    {
        public:
            
        enum Colour
        {
            colour_green=0,
            colour_peach=0,
            colour_white =1,
            colour_yellow =2            
        };
    
        
        void display(Colour myColour);
        
    };
    
    void A::display(A::Colour colour)
    {
        switch(colour)
        {
            case colour_green:
                {
                    cout<<"Colour Green is choosen...\n";
                    break;
                }
            case colour_white:
                {
                    cout<<"Colour White is choosen...\n";
                    break;
                }
            case colour_yellow:
                {
                    cout<<"Colour Yellow is choosen...\n";
                    break;
                }
            degault:
                {
                    cout<<"Invalid Colour choosen...\n";
                    break;
                }
        }
    }
    
    int main()
    {
        A a;
        
        a.display(A::colour_green);
        return(0);
    }
    
    Output:
    
    ./a.out
    Colour Green is choosen...
    
    7. Define the first and last entries of an Enum to use them as loop limits

    Defining the first and last entries of an Enum as colour_first and colour_last or day_first and day_last etc allows us to iterate all the elements in an Enum.

    For Example:

    The code



    Code:
    #include<iostream.h>
    
    class A
    {
        public:
            
        enum Colour
        {
            colour_first,
            colour_green=1,
            colour_peach=2,
            colour_white =3,
            colour_yellow =4,
            colour_last
        };
    
        
        void dispColours();
        
    };
    
    void A::dispColours()
    {
        int colour;
        cout<<"Colours are :\n";
    
        for(colour = colour_first; colour!= colour_last; ++colour)
        {
            cout<<"colour := "<<colour<<endl;
        }
    }
    
    int main()
    {
        A a;
        
        a.dispColours();
        return(0);
    }
    
    Output:
    
    ./a.out
    Colours are :
    colour := 0
    colour := 1
    colour := 2
    colour := 3
    colour := 4
    
    You can write some special methods using switch statement to print enum names as they are.

    8. Beware of pitfalls of assigning explicit values to elements of an enumeartion

    We can even assign specific values to enumeartions as below and in such case looping through the Enum would result iterating through invalid values.

    For Example:

    enum Colour
    {
    Colour_Invalid =0,
    Colour_First =1,
    Colour_White =1,
    Colour_Yellow =5,
    Colour_Red =7,
    Colour_Green =8,
    Colour_Blue =9,
    Colour_Last =9
    }


    Here, attepmting to loop through Colour, would interate through invalid values like 2,3,4 and 6

    9. Reserve the first entry in an Enum defintion as an Invalid entry

    Since many compilers by default assign the first entry of an Enum type to the value 0. So declaring it as an Invalid helps us to catch variables that were not initialised properly as they are more likely to be 0 than any other invalid value.

    For Example:

    enum Color
    {
    Colour_invalid,
    Colour_White,
    Colour_Yellow,
    Colour_Red,
    Colour_Green,
    Colour_Blue,
    }


    Having used the guidelines 7 & 9 in our Application for defining enumerations which helped us for better redability and to catch errors. But it has to be used consistently used whereever needed in the application and at the same time it has to be documented in an application specific coding standards, for the new comers to the project, to understand the same.

    Hope it helps!!
     
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice