Suche…


Grundlegende Aufzählungserklärung

Bei Standard-Enumerationen können Benutzer einen nützlichen Namen für eine Menge von Ganzzahlen angeben. Die Namen werden zusammen als Enumeratoren bezeichnet. Eine Aufzählung und die zugehörigen Enumeratoren sind wie folgt definiert:

enum myEnum
{
    enumName1,
    enumName2,
};

Eine Aufzählung ist ein Typ , der sich von allen anderen Typen unterscheidet. In diesem Fall lautet der Name dieses Typs myEnum . Es wird erwartet, dass Objekte dieses Typs den Wert eines Enumerators innerhalb der Enumeration annehmen.

Die in der Aufzählung deklarierten Enumeratoren sind konstante Werte des Aufzählungstyps. Obwohl die Enumeratoren innerhalb des Typs deklariert sind, ist der Bereichsoperator :: für den Zugriff auf den Namen nicht erforderlich. Der Name des ersten Enumerators lautet also enumName1 .

C ++ 11

Mit dem Bereichsoperator kann optional auf einen Enumerator innerhalb einer Enumeration zugegriffen werden. enumName1 kann also auch als myEnum::enumName1 .

Enumeratoren werden ganzzahlige Werte zugewiesen, beginnend mit 0 und für jeden Enumerator in einer Enumeration um 1 erhöht. Im obigen Fall hat enumName1 den Wert 0, während enumName2 den Wert 1 hat.

Enumeratoren können vom Benutzer auch mit einem bestimmten Wert belegt werden. Dieser Wert muss ein integraler konstanter Ausdruck sein. Enumeratoren, deren Werte nicht explizit angegeben werden, werden auf den Wert des vorherigen Enumerators + 1 gesetzt.

enum myEnum
{
    enumName1 = 1, // value will be 1
    enumName2 = 2, // value will be 2
    enumName3,     // value will be 3, previous value + 1
    enumName4 = 7, // value will be 7
    enumName5,     // value will be 8
    enumName6 = 5, // value will be 5, legal to go backwards
    enumName7 = 3, // value will be 3, legal to reuse numbers
    enumName8 = enumName4 + 2, // value will be 9, legal to take prior enums and adjust them
};

Aufzählung in switch-Anweisungen

Enumeratoren werden häufig für switch-Anweisungen verwendet und erscheinen daher häufig in Zustandsmaschinen. Tatsächlich ist eine nützliche Funktion von switch-Anweisungen mit Enumerationen, dass der Compiler eine Warnung ausgibt, wenn keine Standardanweisung für den Switch enthalten ist und nicht alle Werte der Enumeration verwendet wurden.

enum State {
    start,
    middle,
    end
};

...

switch(myState) {
    case start:
       ...
    case middle:
       ...
} // warning: enumeration value 'end' not handled in switch [-Wswitch]

Iteration über eine Aufzählung

Es ist kein integriertes Programm vorhanden, um die Aufzählung zu durchlaufen.

Es gibt jedoch mehrere Möglichkeiten

  • für eine enum mit nur aufeinander folgenden Werten:

    enum E {
        Begin,
        E1 = Begin,
        E2,
        // ..
        En,
        End
    };
    
    for (E e = E::Begin; e != E::End; ++e) {
        // Do job with e
    }
    
C ++ 11

Mit der enum class muss operator ++ implementiert werden:

E& operator ++ (E& e)
{
    if (e == E::End) {
        throw std::out_of_range("for E& operator ++ (E&)");
    }
    e = E(static_cast<std::underlying_type<E>::type>(e) + 1);
    return e;
}
  • Verwenden eines Containers als std::vector

    enum E {
        E1 = 4,
        E2 = 8,
        // ..
        En
    };
    
    std::vector<E> build_all_E()
    {
        const E all[] = {E1, E2, /*..*/ En};
        
        return std::vector<E>(all, all + sizeof(all) / sizeof(E));
    }
    
    std::vector<E> all_E = build_all_E();
    

    und dann

    for (std::vector<E>::const_iterator it = all_E.begin(); it != all_E.end(); ++it) {
        E e = *it;
        // Do job with e;
    }
    
C ++ 11
  • oder std::initializer_list und eine einfachere Syntax:

    enum E {
        E1 = 4,
        E2 = 8,
        // ..
        En
    };
    
    constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};
    

    und dann

    for (auto e : all_E) {
        // Do job with e
    }
    

Umfangreiche Aufzählungen

In C ++ 11 werden so genannte Bereichsumgebungen eingeführt . Dies sind Aufzählungen, deren Mitglieder mit enumname::membername qualifiziert werden enumname::membername . Bereichs-Enums werden mit der enum class deklariert. So speichern Sie beispielsweise die Farben in einem Regenbogen:

enum class rainbow {
    RED,
    ORANGE,
    YELLOW,
    GREEN,
    BLUE,
    INDIGO,
    VIOLET
};

Um auf eine bestimmte Farbe zuzugreifen:

rainbow r = rainbow::INDIGO;

enum class es können nicht ohne Besetzung implizit in int s konvertiert werden. Also ist int x = rainbow::RED ungültig.

Mit Aufzählungsumgebungen können Sie auch den zugrunde liegenden Typ angeben, dh den Typ , der zur Darstellung eines Members verwendet wird. Standardmäßig ist es int . In einem Tic-Tac-Toe-Spiel können Sie das Stück als speichern

enum class piece : char {
    EMPTY = '\0',
    X = 'X',
    O = 'O',
};

Wie Sie feststellen können, enum kann s ein nachlauf Komma nach dem letzten Mitglied haben.

Vorwärtsdeklaration in C ++ 11 auflisten

Umfangreiche Aufzählungen:

...
enum class Status; // Forward declaration 
Status doWork(); // Use the forward declaration
...
enum class Status { Invalid, Success, Fail };
Status doWork() // Full declaration required for implementation
{
    return Status::Success;
}    

Nicht begrenzte Aufzählungen:

...
enum Status: int; // Forward declaration, explicit type required
Status doWork(); // Use the forward declaration
...
enum Status: int{ Invalid=0, Success, Fail }; // Must match forward declare type
static_assert( Success == 1 );

Ein ausführliches Beispiel für mehrere Dateien finden Sie hier: Beispiel für blinde Obsthändler



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow