Detailed Explanation of Enum Declarations, Definitions, Usage, and Strongly-Typed Enums in C++
Category Programming Technology
Enum Declarations, Definitions, and Usage
As we all know, C/C++ languages can use #define
and const
to create symbolic constants, while the enum
tool not only creates symbolic constants but also defines new data types, but it must be done according to certain rules. Let's take a look at how to use enum
.
Step (One) — Declaration and Definition of Enum Constants
(1) First, consider the following statement:
enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
This statement has two effects:
- First: It declares
enumType
as a new data type, known as an enumeration (enumeration). - Second: It declares
Monday
,Tuesday
, etc., as symbolic constants, commonly referred to as enum constants, with their values defaulting to 0-6 respectively. (Explicit initialization of enum constants will be introduced later)
(2) Next, use the new enum type enumType
to declare variables of this type: enumType Weekday
just like declaring variables with the basic type int
, such as int a;
You can also define enum variables when defining the enum type:
enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday} Weekday;
However, unlike basic variable types, without explicit type conversion, only the defined enum constants can be assigned to variables of this enum type, such as: Weekday = Monday;
or Weekday = Sunday;
Assigning other values to enum variables is not allowed, such as: Weekday = 10;
This is not permitted because 10 is not an enum constant. That means Weekday
can only be one of the defined constants from Monday
to Sunday
. However, this is not absolute; the sixth point will discuss using type casting to assign other types of values to enum variables.
(3) It was mentioned that non-enum constants cannot be assigned to enum variables, but can enum constants be assigned to non-enum variables? For example: int a = Monday;
This is allowed because enum constants are symbolic constants, and the compiler will automatically convert the enum constants to int
type.
(4) Earlier, it was mentioned that assignment operations can be performed on enums, but can enum variables be subjected to arithmetic operations?
Weekday++; Weekday = Monday + Tuesday;
This is illegal because these operations may violate type restrictions, for example:
Weekday = Sunday;
Weekday++;
Weekday
is first assigned the last value in the enum constants, Sunday
(value 6), and then incremented, Weekday
becomes 7, which is invalid for the enumType
type.
Summary: For enums, only the assignment operator is defined; arithmetic operations are not defined for enums.
(5) Arithmetic operations cannot be performed on enum constants, but can enum constants participate in operations with other types of variables?
int a;
a = 1 + Monday;
This is allowed because the compiler will automatically convert the enum constants to int
type.
(6) The second point mentioned: Without explicit type conversion, only the defined enum constants can be assigned to variables of this enum type. The implication is that other types of values can be assigned to enum variables through type casting:
Weekday = enumType(2);
This is equivalent to:
Weekday = Wednesday;
Weekday = enumType(20);
The result will be indeterminate; doing this will not cause an error, but it will not yield the desired result.
Step (Two) — Customizing Enum Constant Values
(1) Earlier, it was mentioned that by defining enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
, the values of Monday
, Tuesday
, etc., default to 0-6 respectively. We can explicitly set the values of enum constants:
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 the values of only some enum constants:
enum enumType {Monday=1, Tuesday, Wednesday=1, Thursday, Friday, Saturday, Sunday};
This way, both Monday
and Wednesday
are defined as 1, so Tuesday=2
, and Thursday
, Friday
, Saturday
, Sunday
default to 2, 3, 4, 5 respectively.
Summary: Enum constants that are not explicitly initialized will default to a value one greater than the previous enum constant.
(3) The second point also illustrates another phenomenon: Enum constant values can be the same.
Step (Three) — Enum Value Range
Earlier, it was mentioned that other types of values can be assigned to enum variables through type casting:
Weekday = enumType(2);
This is legal;
However,
Weekday = enumType(20);
is illegal. This involves the concept of the enum value range: The upper limit of the enum is the smallest power of 2 greater than the largest enum constant, minus 1;
The lower limit of the enum has two cases: First, if the smallest enum constant is not less than 0, the lower limit is 0; second, if the smallest enum constant is less than 0, the lower limit is the largest power of 2 less than the smallest enum constant, plus 1.
For example:
If you define enum enumType1 { First=-5, Second=14, Third=10 };
, then the upper limit of the enum is 16-1=15 (16 is greater than the largest enum constant 14, and is a power of 2); the lower limit of the enum is -8+1=-7 (-8 is less than the smallest enum constant -5, and is a power of 2);
Step (Four) — Enum Applications
Personally, I think enums and switch are the best match:
enum enumType{Step0, Step1, Step2} Step=Step0; // Note that the enum variable Step is directly defined and initialized to Step0 here
switch (Step)
{
case Step0:{...;break;}
case Step1:{...;break;}
case Step2:{...;break;}
default:break;
}
Another less common usage of enums is enum { one, two, three };
, which does not specify a name, so we naturally cannot define some enum types. This is equivalent to defining three constants like static const int one = 0;
. The usage would be int no = one
.
Strongly-Typed Enums
Introduction
Strongly-typed enums, also known as enum classes, are a new syntax in C++11 designed to address the shortcomings of traditional C++ enums. Traditional C++ enum constants are exposed in the outer scope, which means that if two different enum types within the same scope have the same enum constants, they cannot be used together, for example:
enum Side{Right,Left};
enum Thing{Wrong,Right};
This cannot be used together.
Another shortcoming is that traditional enum values are always implicitly converted to integers, and users cannot define custom types. Strongly-typed enums in C++11 address these issues.
Strongly-Typed Enums
Strongly-typed enums are declared using the enum class
syntax, as follows:
enum class Enumeration{
VAL1,
VAL2,
VAL3=100,
VAL4
};
This way, the enum type is secure, and enum values are not implicitly converted to integers; they cannot be compared with integer values, for example, Enumeration::VAL4 == 10
will trigger a compile error.
Additionally, the type used by the enum defaults to int
, but other types can be specified, such as:
enum class Enum:unsigned int{VAL1,VAL2};
As previously mentioned, strongly-typed enums solve the problem of the same enum constant names under different enum classes. When using the enum constant names of an enum type, you must specify the scope, for example: Enum::VAL1
, and VAL1
alone no longer has meaning.
It is also worth mentioning that forward declaration of enums is possible in C++11, for example:
enum class Enum;
enum class Enum1:unsigned int;
Code Snippets of Strongly-Typed Enums in Projects
Image Processing
enum class Color{RED,BLUE,YELLOW,BLACK,WHITE};
Traffic Lights
enum class TrafficLight{RED,YELLOW,GREEN};
Strongly-typed enum values have the functionality of traditional enums—named enum values—and also have the characteristics of classes—members with class scope and inability to perform default type conversions. Hence, they are also referred to as enum classes.
The underlying data of enum classes must be signed or unsigned integers, such as char
, unsigned int
, unsigned long
, with int
being the default.
- Forward Declaration Application
enum class Color:char; // Forward declaration of the enum class void Foo(Color* p); // Usage of forward declaration //.................... enum class Color:char{RED,GREEN,BLACK,WHITE}; // Definition of forward declaration
>
Reference: http://blog.csdn.net/u012333003/article/details/20612267
#
-
** Bdi
* 429**[email protected]
The enumeration type (enumeration) in C++ is a derived data type defined by the user, consisting of a set of enumerated constants:
- (1) Each member (identifier) in the enumeration ends with a
,
not a;
, and the last member can omit the,
; - (2) Negative numbers can be assigned during initialization, and subsequent identifiers still increment by 1;
- (3) Enum variables can only take enumerated constants defined in the enumeration;
- (4) Enum variables can be assigned externally, but type conversion is required;
- (5) Unscoped enum constants can be implicitly converted to
int
, butint
cannot be implicitly converted to enum values; - (6) Each name in the enumeration is assigned an integer value corresponding to its order in the enumeration. By default, the first value is assigned 0, the next value is assigned 1, and so on, but you can explicitly set the values of enum names;
- (7) The values assigned to names do not need to be unique; enum constant values can be repeated;
- (8) In C, the enum type name includes the keyword
enum
, while in C++ it is allowed not to writeenum
, although the C usage is retained; - (9) Enum elements, as constants, have values. C++ compiles them by assigning them values 0, 1, 2, 3, ... according to their order of definition. You can also specify the values of enum elements when declaring the enum type;
- (10) Enum values can be used for comparison;
- (11) An integer cannot be directly assigned to an enum variable;
- (12) Once defined, the elements of the enumeration cannot be changed during program execution.
** Bdi
* 429**[email protected]
** Click to Share Your Notes
-
-
-