Enum (Enumeration) là kiểu dữ liệu do người dùng định nghĩa, cho phép gán tên cho các giá trị nguyên tử (integer constants), giúp code dễ đọc, an toàn kiểu (type-safe) hơn so với #define hoặc const int.
Cú pháp cơ bản (C++98)
enum Gender {
Male,
Female
};
Gender gender = Male; // Giá trị mặc định: Male=0, Female=1
Enum class (C++11) - Khuyến khích dùng
enum class (scoped enum) cung cấp phạm vi (scope) và type safety mạnh hơn:
enum class Color : int { // Có thể chỉ định underlying type
Red = 1,
Green = 2,
Blue = 4
};
Color c = Color::Red; // Phải dùng Color::Red, không phải Red đơn lẻ
// int x = c; // LỖI: Không chuyển ngầm sang int
int x = static_cast<int>(c); // Phải ép kiểu tường minh
Ví dụ hoàn chỉnh
#include <iostream>
using namespace std;
enum class Status {
Pending = 1,
Running = 2,
Success = 3,
Failed = 4
};
void print_status(Status s) {
switch (s) {
case Status::Pending: cout << "Đang chờ"; break;
case Status::Running: cout << "Đang chạy"; break;
case Status::Success: cout << "Thành công"; break;
case Status::Failed: cout << "Thất bại"; break;
}
cout << " (mã: " << static_cast<int>(s) << ")\n";
}
int main() {
Status s = Status::Running;
print_status(s); // Đang chạy (mã: 2)
// So sánh
if (s == Status::Running) cout << "Đang xử lý...\n";
// Duyệt enum (C++20: magic_enum hoặc tự viết)
// C++17: không có built-in iteration
return 0;
}
Đầu ra
Đang chạy (mã: 2) Đang xử lý...
So sánh enum vs enum class
| Đặc điểm | enum (unscoped) | enum class (scoped) |
|---|---|---|
| Phạm vi tên | Global/enclosing scope | Trong enum (Color::Red) |
| Chuyển ngầm sang int | CÓ | KHÔNG (cần static_cast) |
| Chỉ định underlying type | C++11: CÓ | CÓ |
| Forward declaration | Khó khăn | Dễ dàng (C++11) |
Bitmask với enum class (C++11)
enum class Permission : uint8_t {
Read = 1 << 0, // 1
Write = 1 << 1, // 2
Execute = 1 << 2 // 4
};
// Overload operator| để kết hợp quyền
Permission operator|(Permission a, Permission b) {
return static_cast<Permission>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
}
Permission p = Permission::Read | Permission::Write; // = 3
Khuyến nghị
Luôn dùng enum class trong C++11 trở đi để tránh xung đột tên, tăng type safety, và code rõ ràng hơn.