Zakresowa enum class
Typowo bezpieczne wyliczenia
Zakresowa enum class to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C++ Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C++ Academy zawiera 4 lekcji w sumie.
Zwykłe wyliczenia ujawniają nazwy
Klasyczne wyliczenie w stylu C, czyli enum, umieszcza swoje nazwy w otaczającym zakresie i niejawnie konwertuje się do typu int. Ułatwia to kolizje nazw i przypadkowe porównania.
- enum class rozwiązuje oba problemy.
- Wartości mają własny zakres i są silnie typowane.
#include <iostream>
enum Color { Red, Green, Blue };
int main() {
Color c = Green;
int x = c; // implicit conversion to int
std::cout << x << "\n";
}Deklarowanie wyliczenia o własnym zakresie
Dodaj słowo kluczowe class (lub struct), aby utworzyć wyliczenie o własnym zakresie. Od tej pory każdą wartość trzeba poprzedzać nazwą wyliczenia.
#include <iostream>
enum class Color { Red, Green, Blue };
int main() {
Color c = Color::Green;
if (c == Color::Green) std::cout << "green\n";
}Brak niejawnej konwersji
Wyliczenie o własnym zakresie nie konwertuje się niejawnie do typu int. Zapobiega to błędom, w których wyliczenie zostaje przypadkowo użyte w działaniach arytmetycznych.
- Aby uzyskać liczbę, trzeba wykonać rzutowanie jawne.
#include <iostream>
enum class Color { Red, Green, Blue };
int main() {
Color c = Color::Blue;
int n = static_cast<int>(c); // explicit
std::cout << n << "\n"; // prints 2
}Typ bazowy
Domyślnym typem bazowym jest int, ale można wybrać mniejszy lub konkretny typ całkowity, aby oszczędzić miejsce albo dopasować się do protokołu.
#include <iostream>
#include <cstdint>
enum class Status : std::uint8_t { Ok = 0, Warn = 1, Error = 2 };
int main() {
Status s = Status::Warn;
std::cout << static_cast<int>(s) << "\n";
}Własne wartości
Można przypisać jawne wartości elementom wyliczenia. Wartości występujące po jawnie określonej wartości są nadal zwiększane kolejno od niej.
#include <iostream>
enum class Http { Ok = 200, NotFound = 404, ServerError = 500 };
int main() {
Http h = Http::NotFound;
std::cout << static_cast<int>(h) << "\n";
}Używanie wyliczenia w switch
Wyliczenia świetnie sprawdzają się w instrukcjach switch. Wypisanie każdego przypadku jasno pokazuje intencję i pozwala kompilatorowi ostrzegać o pominiętych przypadkach.
#include <iostream>
enum class Dir { North, East, South, West };
const char* name(Dir d) {
switch (d) {
case Dir::North: return "N";
case Dir::East: return "E";
case Dir::South: return "S";
case Dir::West: return "W";
}
return "?";
}
int main() { std::cout << name(Dir::East) << "\n"; }Wyliczenia jako argumenty funkcji
Przekazywanie wyliczenia o własnym zakresie znacznie lepiej komunikuje intencję niż przekazywanie zwykłego int lub bool. Kompilator wymusza używanie wyłącznie prawidłowych wartości wyliczenia.
#include <iostream>
enum class Align { Left, Center, Right };
void render(const char* text, Align a) {
std::cout << text << " aligned " << static_cast<int>(a) << "\n";
}
int main() { render("Hi", Align::Center); }Porównywanie wartości wyliczenia
Wyliczenia o własnym zakresie bezpośrednio obsługują operatory == i !=. Działają również operatory relacyjne (<, >), ponieważ wartości są uporządkowane.
#include <iostream>
enum class Level { Low, Medium, High };
int main() {
Level l = Level::High;
std::cout << (l > Level::Low ? "above low\n" : "low\n");
}Iterowanie w ujęciu koncepcyjnym
Wyliczenia nie są automatycznie iterowalne, ale często stosuje się rzutowanie za pośrednictwem bazowych wartości całkowitych. Warto zachować znacznik końcowy, taki jak Count, aby znać zakres.
#include <iostream>
enum class Coin { Penny, Nickel, Dime, Count };
int main() {
for (int i = 0; i < static_cast<int>(Coin::Count); ++i)
std::cout << i << " ";
std::cout << "\n";
}Dlaczego bezpieczeństwo typów ma znaczenie
Nie można przypadkowo mieszać dwóch niezwiązanych wyliczeń o własnych zakresach, nawet jeśli oba mają wartość o nazwie None. Kompilator traktuje je jako różne typy.
#include <iostream>
enum class Fruit { None, Apple };
enum class Tool { None, Hammer };
int main() {
Fruit f = Fruit::None;
// Tool t = f; // would NOT compile
std::cout << (f == Fruit::None) << "\n";
}Kiedy używać zwykłych wyliczeń
Zwykłe wyliczenia nadal występują w starszych interfejsach API i kodzie używającym flag bitowych, gdzie wygodna jest niejawna konwersja do int. W nowym kodzie należy preferować enum class, chyba że istnieje konkretny powód, aby tego nie robić.
Szybki test
Sprawdź swoją wiedzę na temat wyliczeń o własnym zakresie.
Podsumowanie
Dowiedział się Pan o wyliczeniach o własnym zakresie:
enum classogranicza zakres wartości i blokuje niejawną konwersję do int.- Używaj
static_cast<int>, aby odczytać liczbę. - Wybierz typ bazowy za pomocą
: type. - Preferuj
enum classw kodzie bezpiecznym typowo i jasno dokumentującym swoje przeznaczenie.
Często zadawane pytania
Czy lekcja „Zakresowa enum class” jest bezpłatna?
Tak — pełny tekst „Zakresowa enum class” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C++ Academy, przejdź na CoddyKit PRO. Kurs C++ Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Zakresowa enum class”?
Typowo bezpieczne wyliczenia Ćwiczysz C++ Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C++ Academy?
Nie wymagamy żadnego doświadczenia. C++ Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Zakresowa enum class”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C++ Academy?
Tak. Każda lekcja C++ Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Zakresowa enum class
- Unie i związane z nimi ryzyko
- std::variant
- std::visit