Enumerator declaration, definition, and usage
As we all know, the C/C++ language can use#defineandconstto create symbolic constants, and usingenumtool can not only create symbolic constants, but also define new data types, but it must be done according to certain rules. Let's take a look atenumits usage.
Step (1) — Declaration and definition of enumerators
(1) First, look at the following statement:
enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
This statement has two functions:
- First: It declares enumType as a new data type, called an enumeration;
- Second: It declares Monday, Tuesday, etc. as symbolic constants, usually called enumerators, whose default values are 0-6 respectively. (We will introduce how to explicitly initialize enumerator values later.)
(2)Then use the new enumeration type enumType to declare variables of this type: enumType Weekday, just like declaring a variable with the basic variable type int, e.g., int a; you can also define enumeration variables when defining the enumeration type.
enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}Weekday;
However, unlike basic variable types, without a cast, you can only assign the defined enumerators to a variable of that enumeration type. For example: Weekday = Monday; or Weekday = Sunday; You cannot assign other values to an enumeration variable, e.g., Weekday = 10; This is not allowed because 10 is not an enumerator. In other words, Weekday can only be the defined enumerators Monday-Sunday. But this is not absolute; the sixth point will discuss using a cast to assign values of other types to enumeration variables.
(3)It was stated above that non-enumerator values cannot be assigned to enumeration variables. Then can enumerators be assigned to non-enumeration variables? For example:int a=Monday;This is allowed, because enumerators are symbolic constants. In this assignment, the compiler will automatically convert the enumerator to int type.
(4)Earlier we said that assignment operations can be performed on enumerations. Can enumeration variables undergo arithmetic operations?
Weekday++;Weekday = Monday + Tuesday;
This is illegal, because these operations may lead to violations of type restrictions. For example:
Weekday = Sunday; Weekday++;
Weekday is first assigned the last enumerator value Sunday (value 6). If incremented further, Weekday would increase to 7, but 7 is invalid for the enumType type.
Summary:For enumerations, only the assignment operator is defined; arithmetic operations are not defined for enumerations.
(5)Arithmetic operations cannot be performed on enumerators. Then can enumerators participate in operations with variables of other types?
int a; a = 1 + Monday;
This is allowed, because the compiler will automatically convert enumerators to int type.
(6)The second point said: without a cast, only the defined enumerators can be assigned to a variable of that enumeration type. The implication is that values of other types can be assigned to enumeration variables through a cast:
Weekday = enumType(2);
Equivalent to:
Weekday = Wednesday;But what would happen if you tried to assign a value outside the value range of the enumeration to an enumeration variable through a cast?
Weekday = enumType(20);
The result will be undefined. Doing this will not cause an error, but you will not get the desired result.
Step (2) — Customizing enumerator values
(1)Earlier we talked about definingenum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};The enumerators Monday, Tuesday, etc. have default values 0-6 respectively. We can explicitly set the values of enumerators:
enum enumType {Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6, Sunday=7};
The specified values must be integers!
(2)You can also explicitly define only some of the enumerator values:
enum enumType {Monday=1, Tuesday, Wednesday=1, Thursday, Friday, Saturday, Sunday}; In this way, both Monday and Wednesday are defined as 1, so Tuesday=2, and the default values of Thursday, Friday, Saturday, and Sunday are 2, 3, 4, 5 respectively.
Summary:The value of an uninitialized enumerator defaults to 1 greater than the preceding enumerator's value.
(3)The second point also illustrates another phenomenon: enumerator values can be the same.
Step (3) — The value range of an enumeration
Earlier it was mentioned that values of other types can be assigned to enumeration variables through a cast:
Weekday = enumType(2);
This is legal;
But
Weekday = enumType(20);
is illegal. This involves the concept of the value range of an enumeration: The upper bound of an enumeration is the smallest power of 2 that is greater than the maximum enumerator, minus 1;
The lower bound of an enumeration has two cases: 1. If the minimum enumerator value is not less than 0, the lower bound is 0; 2. If the minimum enumerator value is less than 0, the lower bound is the largest power of 2 that is less than the minimum enumerator, plus 1.
For example:
Suppose we defineenum enumType1 { First=-5,Second=14,Third=10 };Then the upper bound of the enumeration is 16-1=15 (16 is greater than the maximum enumerator 14, and is a power of 2); the lower bound is -8+1=-7 (-8 is less than the minimum enumerator -5, and is a power of 2).
Step (4) — Enumeration applications
Personally, I think enum and switch are the best partners:
enum enumType{Step0, Step1, Step2}Step=Step0; // 注意这里在声明枚举的时候直接定义了枚举变量 Step,并初始化为 Step0
switch (Step)x
{
case Step0:{...;break;}
case Step1:{...;break;}
case Step2:{...;break;}
default:break;
}
Additionally, there is a rare usage of enum, which isenum { one ,two ,three};that is, not specifying a name. In this way, naturally we cannot define enumeration types. At this point it is equivalent tostatic const int one = 0;defining three constants like this. Then when using it, you justint no = one。
Strongly-typed enums
1. Brief description
Strongly-typed enums, also known as enum classes, are new syntax in C++11, used to solve the defects of traditional C++ enumeration types. In traditional C++, enumeration constants are exposed to the outer scope, so if there are two different enumeration types in the same scope, they cannot contain the same enumeration constant. For example:
enum Side{Right,Left};
enum Thing{Wrong,Right};
They cannot be used together.
Another defect is that traditional enumeration values are always implicitly converted to integers, and users cannot define the underlying type. Strongly-typed enums in C++11 solve these problems.
2. Strongly-typed enums
Strongly-typed enums use the `enum class` syntax to declare, as follows:
enum class Enumeration{
VAL1,
VAL2,
VAL3=100,
VAL4
};
In this way, the enumeration type is safe, and enumerator values will not be implicitly converted to integers, nor can they be compared with integer values. For example (`Enumeration::VAL4 == 10` will trigger a compile error).
In addition, the underlying type used by the enumeration type defaults to `int`, but other types can also be specified, for example:
enum class Enum:unsigned int{VAL1,VAL2};
As mentioned earlier, strongly-typed enums can solve the problem of traditional enums having the same enumerator names in different enumeration classes. When using an enumerator of an enumeration type, you must specify its scope, for example: `Enum::VAL1`, while `VAL1` alone no longer has meaning.
Another point worth noting is that forward declaration of enumeration types is also feasible in C++11, for example:
enum class Enum; enum class Enum1:unsigned int;
3. Strongly-typed enum code snippets in projects
1. Image processing
enum class Color{RED,BLUE,YELLOR,BLACK,WHITE};
2. Traffic lights
enum class TrafficLight{RED,YELLOR,GREEN};
Strongly-typed enumerators have the functionality of traditional enums — naming enumerator values — and also have class-like characteristics: they have class-scoped members and cannot undergo default type conversion. Therefore, they are also called enum classes — `enum class`.
The underlying data type of an enum class must be a signed or unsigned integer type, such as `char`, `unsigned int`, `unsigned long`; the default is `int`.
3. Forward declaration application
enmu class Clolor:char; //前置声明枚举类
void Foo(Color*p); //前置声明的使用
//....................
enum class Color:char{RED,GREEN,BLACK,WHITE}; //前置声明的定义
Reference: http://blog.csdn.net/u012333003/article/details/20612267