Enumerated data types (or enums) in C++ provide a way to create a set of named integer constants. They make your code more readable and maintainable by replacing arbitrary numeric values with meaningful names. Here's how to use them:
1. Declaration:
enum Color {
RED,
GREEN,
BLUE,
YELLOW
};
This declares an enum named Color
with four enumerators: RED
, GREEN
, BLUE
, and YELLOW
. By default, the first enumerator is assigned the value 0, the second 1, and so on.
2. Usage:
Color myColor = BLUE;
if (myColor == GREEN) {
std::cout << "My color is green!" << std::endl;
} else if (myColor == RED) {
std::cout << "My color is red!" << std::endl;
} else {
std::cout << "My color is something else." << std::endl;
}
// You can also use enums in switch statements:
switch (myColor) {
case RED:
std::cout << "It's red!" << std::endl;
break;
case GREEN:
std::cout << "It's green!" << std::endl;
break;
// ... other cases
default:
std::cout << "Some other color." << std::endl;
}
3. Underlying Type and Explicit Values:
Enums are implicitly convertible to integers. You can also explicitly assign integer values to enumerators:
enum TrafficLight {
RED = 10,
YELLOW = 20,
GREEN = 30
};
TrafficLight light = YELLOW;
int lightValue = light; // lightValue will be 20
// You can also cast an integer to an enum (but be careful!):
TrafficLight anotherLight = static_cast<TrafficLight>(10); // anotherLight is now RED
4. Scoped Enums (C++11 and later):
Scoped enums (or enum classes) are a stronger type of enum introduced in C++11. They prevent implicit conversions to integers and provide better type safety:
enum class Fruit {
APPLE,
BANANA,
ORANGE
};
Fruit myFruit = Fruit::BANANA;
// You CANNOT do this:
// int fruitValue = myFruit; // Error: No implicit conversion
// You MUST do this:
int fruitValue = static_cast<int>(myFruit); // Explicit conversion
if (myFruit == Fruit::APPLE) { // Must use Fruit::
// ...
}
Why use enums?
- Readability:
Color::BLUE
is much more understandable than2
. - Maintainability: If you need to change the value associated with a color, you only need to change it in the enum declaration, not throughout your code.
- Type Safety (especially with scoped enums): Enums prevent you from accidentally assigning arbitrary integer values to variables that should only hold specific named values. This helps catch errors at compile time.
Example: A more complete example:
#include <iostream>
enum class Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
};
std::ostream& operator<<(std::ostream& os, const Day& day) {
switch (day) {
case Day::MONDAY: return os << "Monday";
case Day::TUESDAY: return os << "Tuesday";
// ... other days
default: return os << "Unknown Day";
}
}
int main() {
Day today = Day::WEDNESDAY;
std::cout << "Today is " << today << std::endl;
for (Day d = Day::MONDAY; d <= Day::SUNDAY; d = static_cast<Day>(static_cast<int>(d) + 1)) {
std::cout << d << std::endl; // Demonstrating iteration (be careful with this!)
}
return 0;
}
This example shows how to use enums with a switch
statement, how to overload the <<
operator to print enum values in a user-friendly way, and how to (carefully) iterate through an enum. Remember to be cautious when casting integers to enums, especially unscoped ones, as it can lead to unexpected behavior if the integer doesn't correspond to a valid enumerator. Scoped enums are generally preferred for their increased type safety.
0 件のコメント:
コメントを投稿