ProgrammierungSenior C++ Entwickler

Erzählen Sie von dem Mechanismus 'enum class' (scoped enums) in C++. Wie unterscheidet er sich von gewöhnlichen Enumerationen und warum wurde er eingeführt? Welche typischen Fehler treten beim Übergang von alten enums zu enum class auf?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

In C++11 wurde der Mechanismus 'scoped enums' — das Schlüsselwort enum class — eingeführt.

Hauptunterschiede zu klassischen enums:

  • Der Inhalt von enum class hat einen eigenen Geltungsbereich (Scope), es gibt keine Verunreinigung des globalen Namensraums.
  • Es findet keine implizite Umwandlung von Aufzählungswerten zu int statt (eine explizite Umwandlung ist erforderlich).
  • Der Typ von enum class ist standardmäßig: int, kann aber anders festgelegt werden (zum Beispiel enum class MyE : uint8_t { ... };).

Warum ist das notwendig: Um die Typensicherheit zu erhöhen, Namenskonflikte zu verhindern, fehlerhafte Vergleiche zu vermeiden und die Speicherung explizit zu steuern.

Beispiel:

enum Color { Red, Green }; Color c = Red; // Gewöhnliches enum, Red ist global sichtbar enum class State { Off, On }; State s = State::On; // Es muss State::On angegeben werden

Das kann man nicht schreiben:

enum class State { Off, On }; int x = State::On; // Fehler! Nur mit Casting int y = static_cast<int>(State::Off); // OK

Hinterhältige Frage

Warum kann man keine logische Vergleich zwischen Werten verschiedener enum classes anstellen, selbst wenn sie gleiche Namen und den gleichen zugrunde liegenden Typ haben?

Antwort:

Typensicherheit: Jede enum class ist ein eigener Typ, selbst wenn der zugrunde liegende Typ derselbe ist und die Aufzählungswerte die gleichen Namen haben. Der Compiler betrachtet sie als verschiedene Typen und erlaubt keinen impliziten Vergleich.

Beispiele für reale Fehler aufgrund fehlender Kenntnisse der Feinheiten des Themas.


Geschichte

Beim Übergang von enum zu enum class in einem Projekt zur Maschinensteuerung wurde vergessen, eine explizite Umwandlung beim Ausgeben von Werten ins Log hinzuzufügen. Die Logs begannen "fremde" Werte anzuzeigen (State::On wurde nicht als Zahl erkannt), was das Debuggen erschwerte.


Geschichte

In einem REST-Service verglich der Code nach der Migration von gewöhnlichen enums zu enum class Werte aus verschiedenen Aufzählungen von unterschiedlichen enum classes. Der Compiler ließ das nicht zu, die automatischen Tests konnten nicht mehr kompiliert werden.


Geschichte

Im Auditsystem verwechselten die Entwickler die alte und neue Syntax — manchmal erklärten sie versehentlich enum class, verwendeten aber die Enumerator ohne Qualifikator, was dazu führte, dass nicht der richtige Code kompiliert wurde oder Linker-Fehler aufgrund von Namenskonflikten auftraten.