C++ Tutorial

 enum Datentyp

Der enumerated Datentyp, im Folgenden vereinfacht enum genannt, dient zur Definition von mehreren, logisch zusammengehörigen, Konstanten in einer Anweisung.

unscoped enum

Die minimale Definition eines unscoped enums sieht wie folgt aus:

enum Ename {EN1, EN2,...} myEnum;
Ename yourEnum;

Die erste Anweisung definiert den enum-Datentyp Ename sowie die enum-Variable myEnum. EN1, EN2 und EN3 sind die dem enum-Datentyp zugeordneten Konstanten und werden als Enumeratoren bezeichnet.

Die zweite Anweisung definierte eine enum-Variable ebenfalls vom Datentyp Ename.

Ein Enumerator kann einer Variable mit einem (fast) beliebigen Datentyp zugewiesen werden, aber einer enum-Variable nur ein Enumerator ihres enum-Datentyps.

Die internen Werte für Enumeratoren werden, beginnend ab der Wert 0, jeweils um eins erhöht. Soll ein Enumerator einen bestimmten Wert erhalten, wird ihm explizit ein Wert zugewiesen. Die nachfolgenden Enumeratoren werden dann wieder fortlaufend inkrementiert.

// Werte der Enumeratoren: EN1=0, EN2=10, EN3=11
enum Ename {EN1, EN2=10, EN3} myEnum;

Ferner ist bei der Verwendung von unscoped enums zu beachten, dass die Namen der Enumeratoren eindeutig sind. D.h., gleichnamige Daten oder Enumeratoren in unterschiedlichen enums führen zu einem Übersetzungsfehler.

enum heater {OFF, MIN=0x10, NORM, MAX};
enum wiper {OFF, INTERVALL, CONTINOUS};   // Fehler, da OFF doppelt definiert

Das nachfolgende Beispiel zeigt den Einsatz eines enums anhand einer fiktiven Sitzheizungssteuerung.

#include <iostream>
#include <format>

// enum definieren
// Werte der Enumeratoren: OFF=0, MIN=0x10, NORM=0x11, MAX=0x12
enum heater {OFF, MIN=0x10, NORM, MAX};
// enum Variable definieren
heater seatheater;

int main()
{
   // Sitzheizung initialisiieren
   seatheater = OFF;
   // Schleife wird verlassen, wenn die Sitzheizung erneut OFF ist
   do
   {
      // Sitzheizungsstatus auswerten und je nach
      // aktuellem Zustand den naechsten Zustand schalten
      switch(seatheater)
      {
         case OFF:
           seatheater = MAX;
           break;
         case MAX:
            seatheater = NORM;
            break;
         case NORM:
            seatheater = MIN;
            break;
         case MIN:
            seatheater = OFF;
            break;
      }
      std::cout << std::format("Die Sitzheizung ist {:#x}\n",seatheater);
   } while(seatheater != OFF);
}

scoped enum

Um Fehler durch gleichnamige Enumeratoren in verschiedenen enums zu vermeiden, wird der scoped enum verwendet. Seine Definition gleicht bis auf das Schlüsselwort class der des unscoped enums.

enum class EName {EN1, EN2, EN3} myEnum;
EName yourEnum;

Beim Einsatz des scoped enum ist zu beachten, dass

  • die Enumeratoren stets vollständig qualifiziert angegeben werden müssen, d.h. immer zusammen mit dem Namen des enum-Datentyps (z.B. Ename::EN1),
  • die Enumeratoren nur enum-Variablen des gleichen enum-Datentyps zugewiesen werden können,
  • mit Enumeratoren nicht ohne Weiteres Rechen- oder Logikoperationen ausgeführt werden können, d.h. der Ausdruck EName::EN2 | EName::EN3 ist zunächst nicht zulässig. Wie trotzdem solche Operationen durchgeführt werden können, ist Thema des Kapitels 'Überladene binäre Operatoren',
  • und enum-Variablen können ohne Typkonvertierung nicht ausgegeben werden.
// Scoped-enum am Beispiel einer Ampelsteuerung
// Es wird ein Ampelzyklus (rot...rot) durchlaufen

#include <iostream>

// Enum fuer die Ampelfarben
enum class Ampel {ROT, ROT_GELB, GRUEN, GELB};

int main()
{
   // Ampel-Variable definieren/initialisieren
   Ampel ampl = Ampel::ROT;
   std::cout << "Die Ampel ist Rot\n";
   // Ampelzyklus durchlaufen bis Ampel wieder Rot ist
   do
   {
      switch (ampl)
      {
      case Ampel::ROT:
         ampl = Ampel::ROT_GELB;
         std::cout << "Die Ampel ist Rot-Gelb\n";
         break;
      case Ampel::ROT_GELB:
         ampl = Ampel::GRUEN;
         std::cout << "Die Ampel ist Gruen\n";
         break;
      case Ampel::GRUEN:
         ampl = Ampel::GELB;
         std::cout << "Die Ampel ist Gelb\n";
         break;
      case Ampel::GELB:
         std::cout << "Die Ampel ist Rot\n";
         ampl = Ampel::ROT;
      }
   } while (ampl != Ampel::ROT);
}