Enumerations

 Introduction

Consider that, when creating a program for a real estate company that sells houses, you want the program to ask a customer the type of house that he or she wants to purchase and/or the type of garage that the desired house should have. Here is an example:

```using namespace System;

int main()
{
int TypeOfHouse  = 0;
int TypeOfGarage = 0;

Console::WriteLine(L"Enter the type of house you want to purchase");
Console::WriteLine(L"1 - Single Family");
Console::WriteLine(L"2 - Townhouse");
Console::WriteLine(L"3 - Condominium");

Console::WriteLine(L"Enter the type of garage you want");
Console::WriteLine(L"0 - Doesn't matter");
Console::WriteLine(L"1 - Interior");
Console::WriteLine(L"2 - Exterior");

Console::WriteLine(L"\nYou selected: {0}", TypeOfHouse);
Console::WriteLine(L"Type of Garage: {0}", TypeOfGarage);

return 0;
}```

Here is an example of running the program:

 ```Enter the type of house you want to purchase 1 - Single Family 2 - Townhouse 3 - Condominium Your Choice: 1 Enter the type of garage you want 0 - Doesn't matter 1 - Interior 2 - Exterior Your Choice: 2 You selected: 2 Type of Garage: 0 Press any key to continue . . .```

For such a program, the numbers can be vague. 1 can be considered a general number but, in our program, it can represent a Single Family house or an Interior type of garage. At the same time, our program uses the constant 1 in particular meaningful ways. To make it possible to give more meaning to a constant number, when the number can be made part of a series, C++ allows you to create a type of list.

An enumerator is a series of constant integers that each has a specific position in the list and can be recognized by a meaningful name. Based on this, instead of just remembering that the constant 1 represents Single Family, you can create a list that has that type of house. In another list, instead of using 1 again, you can give it a name. Consequently, in each list, although the constant 1 would still be considered, at least it would mean something precise.

To create an enumerator, you use the enum keyword, followed by the name of the enumerator, followed by a name for each item of the list. The name of the enumerator and the name of each item of the list follows the rules we reviewed for names in C++. The formula of creating an enumeration is:

`enum Series_Name {Item1, Item2, Item_n};`

Here is an example:

```using namespace System;

int main()
{
enum HouseType { Unknown, SingleFamily, TownHouse, Condominium };

return 0;
}```

After creating an enumerator, each item in the list is referred to as a member of the enumerator.

 Indexing the Members of an Enumeration

Each member is assigned a constant number. The members are counted starting at 0, then 1, etc. By default, the first member in the enumerator is assigned the number 0, the second is 1, etc. This is referred to as the index. In fact, you can use Write() or WriteLine() to show the index of a member. This is illustrated in the following program:

```using namespace System;

int main()
{
enum HouseType { Unknown, SingleFamily, TownHouse, Condominium };

Console::Write(L"Member Index: ");
Console::WriteLine(Unknown);
Console::Write(L"Member Index: ");
Console::WriteLine(SingleFamily);
Console::Write(L"Member Index: ");
Console::WriteLine(TownHouse);
Console::Write(L"Member Index: ");
Console::WriteLine(Condominium);

return 0;
}```

This would produce:

```Member Index: 0
Member Index: 1
Member Index: 2
Member Index: 3
Press any key to continue . . .```

In this HouseType enumeration, the Unknown member has an index 0. The SingleFamily member has an index of 1. The TownHouse member has an index of 2.

You can specify or change the numbers to your liking when you create the enumeration but once the enumeration has been created, whether you specified these numbers or not, they cannot be changed.

To make the list start at a specific number, assign the starting value to the first item in the list. Here is an example:

```using namespace System;

int main()
{
enum HouseType { Unknown = 5, SingleFamily, TownHouse, Condominium };

Console::Write(L"Member Index: ");
Console::WriteLine(Unknown);
Console::Write(L"Member Index: ");
Console::WriteLine(SingleFamily);
Console::Write(L"Member Index: ");
Console::WriteLine(TownHouse);
Console::Write(L"Member Index: ");
Console::WriteLine(Condominium);

return 0;
}```

This would produce:

```Member Index: 5
Member Index: 6
Member Index: 7
Member Index: 8
Press any key to continue . . .```

This time, the Unknown member has a value of 5, the SingleFamily member has a value of 6, etc. When creating the enumeration, you can assign any value of your choice to any member of the enumeration, or you can set different ranges of values to various items. You can create a list like this:

```using namespace System;

int main()
{
enum HouseType { Unknown, SingleFamily, TownHouse, Condominium = 6 };

Console::Write(L"Member Index: ");
Console::WriteLine(Unknown);
Console::Write(L"Member Index: ");
Console::WriteLine(SingleFamily);
Console::Write(L"Member Index: ");
Console::WriteLine(TownHouse);
Console::Write(L"Member Index: ");
Console::WriteLine(Condominium);

return 0;
}```

This would produce:

```Member Index: 0
Member Index: 1
Member Index: 2
Member Index: 6
Press any key to continue . . .```

As mentioned already, you can assign any value to any member of the enumeration. You can even assign the same number to different members. Here are examples:

```using namespace System;

int main()
{
enum HouseType { Unknown = 4, SingleFamily, TownHouse = 12, Condominium };

Console::Write(L"Member Index: ");
Console::WriteLine(Unknown);
Console::Write(L"Member Index: ");
Console::WriteLine(SingleFamily);
Console::Write(L"Member Index: ");
Console::WriteLine(TownHouse);
Console::Write(L"Member Index: ");
Console::WriteLine(Condominium);

return 0;
}```

This would produce:

```Member Index: 4
Member Index: 5
Member Index: 12
Member Index: 13
Press any key to continue . . .```

We mentioned that an enumeration must be an integer type. This meant that the members can represent Byte, short, int, long or even char types. As we have demonstrated so far, by default, the members of an enumeration are of type int. When creating the elements of an enumeration, you can initialize them to specify the type of values that they would have. For example, if you want the members to be compared to character types, initialize them with single-quoted symbols. Here is an example:

```public enum class FlowerArrangement
{
Bouquet = L'U',
Vase    = L'V',
Bundle  = L'D',
Any
};```

Notice you don't have to initialize all members, only those for whom you want to specify a specific value.

 Declaring an Enumeration Variable

After creating an enumeration, it can be used as a data type and you can declare a variable from it. One of the formulas you can use is:

`Series_Name VariableName;`

Here is an example:

```using namespace System;

int main()
{
enum HouseType { Unknown, SingleFamily, TownHouse, Condominium };

HouseType hType;

return 0;
}```

When you declare a variable using an enumerator, the variable is initialized to the value of the first member of the enumeration. To initialize a variable declared from an enumeration, assign the name of the desired member to the variable. Here is an example:

```using namespace System;

int main()
{
enum HouseType { Unknown, SingleFamily, TownHouse, Condominium };

HouseType hType = SingleFamily;

Console::Write(L"Enumerator: ");
Console::WriteLine(hType);

return 0;
}```

This would produce:

```Enumerator: 1
Press any key to continue . . .```

As done with the other variables, you can declare more than one variable of an enumerator type. Here is an example:

```using namespace System;

int main()
{
enum HouseType { Unknown, SingleFamily, TownHouse, Condominium };

HouseType hHouse = SingleFamily;
HouseType apart  = Condominium;

return 0;
}```

Instead of declaring the variable(s) after the list has been created, you can declare the variables of the enumeration type on the right side of the list but before the closing semi-colon. Here is an example:

```using namespace System;

int main()
{
enum HouseType
{
Unknown,
SingleFamily,
TownHouse,
Condominium
} hHouse;

hHouse = SingleFamily;
HouseType apart  = Condominium;

Console::Write(L"Enumerator: ");
Console::WriteLine(hHouse);

return 0;
}```

You can also initialize he variable(s) when declaring it(them). Here is an example:

```using namespace System;

int main()
{
enum HouseType
{
Unknown,
SingleFamily,
TownHouse,
Condominium
} hHouse = SingleFamily, apart  = Condominium;

Console::Write(L"Enumerator: ");
Console::WriteLine(hHouse);

return 0;
}```
 Global Enumerations

An enumeration is referred to as global when it is created outside of any function or class. For example, you can create an enumeration above main() to make it global:

```using namespace System;

enum HouseType { Unknown, SingleFamily, TownHouse, Condominium };

int main()
{
return 0;
}```

After creating a global enumeration, you can use it as you see fit. For example, you can use it directly in your source code or you can declare its variable where you see fit. Here is an example:

```using namespace System;

enum HouseType { Unknown, SingleFamily, TownHouse, Condominium };

int main()
{
HouseType hType;

return 0;
}```

When we study functions, we will see that a global enumeration can be accessed from any function of the same source file.

 Enumerations and Assemblies

By default, if you create an enumeration the way we have proceeded so far, it would be available only in the assembly it belongs to. Just we reviewed for a class, you can control an enumeration's accessibility outside of its assembly. This means that you can hide or make it visible outside of its assembly. To do this, you can precede it with the private or the public keyword. Here is an example:

```using namespace System;

public enum HouseType { Unknown, SingleFamily, TownHouse, Condominium };

int main()
{
HouseType hType;

return 0;
}```