Ich habe gehört, dass einige Leute empfehlen, in C++ enum Klassen zu verwenden, wegen ihrer Typsicherheit.
Aber was bedeutet das wirklich?
Ich habe gehört, dass einige Leute empfehlen, in C++ enum Klassen zu verwenden, wegen ihrer Typsicherheit.
Aber was bedeutet das wirklich?
C++11 FAQ erwähnt die folgenden Punkte:
konventionelle Aufzählungstypen konvertieren implizit in int, was zu Fehlern führt, wenn jemand nicht möchte, dass eine Aufzählung als Ganzzahl fungiert.
enum Farbe
{
Rot,
Grün,
Gelb
};
enum class NeueFarbe
{
Rot_1,
Grün_1,
Gelb_1
};
int main()
{
//! Implizite Konvertierung ist möglich
int i = Rot;
//! Benötigen Sie den Aufzählungstypen gefolgt von Zugriffsmodifizierer. Bsp: NeueFarbe::Rot_1
int j = Rot_1; // Fehler C2065: 'Rot_1': nichtdeklarierter Bezeichner
//! Implizite Konvertierung ist nicht möglich. Lösung Bsp: int k = (int)NeueFarbe::Rot_1;
int k = NeueFarbe::Rot_1; // Fehler C2440: 'Initialisierung': Kann nicht von 'NeueFarbe' in 'int' konvertiert werden
return 0;
}
Konventionelle Aufzählungstypen exportieren ihre Elemente in den umgebenden Bereich, was zu Namenskonflikten führt.
// Header.h
enum Fahrzeug
{
Auto,
Bus,
Fahrrad,
Autorikscha
};
enum Vierrad
{
Auto, // Fehler C2365: 'Auto': Neudefinition; vorherige Definition war 'Element'
Kleinbus
};
enum class Editor
{
vim,
eclipes,
VisualStudio
};
enum class CppEditor
{
eclipes, // Kein Fehler bei Neudefinitionen
VisualStudio, // Kein Fehler bei Neudefinitionen
QtCreator
};
Der zugrunde liegende Typ eines Aufzählungstyps kann nicht spezifiziert werden, was zu Verwirrung, Kompatibilitätsproblemen und der Unmöglichkeit der Vorwärtsdeklaration führt.
// Header1.h
#include
using namespace std;
enum class Port : unsigned char; // Vorwärtsdeklaration
class MyClass
{
public:
void PrintPort(enum class Port p);
};
void MyClass::PrintPort(enum class Port p)
{
cout << (int)p << endl;
}
.
// Header.h
enum class Port : unsigned char // Deklarieren Sie den Aufzählungstypen explizit
{
PORT_1 = 0x01,
PORT_2 = 0x02,
PORT_3 = 0x04
};
.
// Source.cpp
#include "Header1.h"
#include "Header.h"
using namespace std;
int main()
{
MyClass m;
m.PrintPort(Port::PORT_1);
return 0;
}
Eine Sache, die nicht explizit erwähnt wurde - das Scope-Feature gibt Ihnen die Möglichkeit, für eine Enum und eine Klassenmethode denselben Namen zu haben. Zum Beispiel:
class Test
{
public:
// Diese rufen intern ProcessCommand() auf
void TakeSnapshot();
void RestoreSnapshot();
private:
enum class Command // wäre ohne 'class' nicht möglich
{
TakeSnapshot,
RestoreSnapshot
};
void ProcessCommand(Command cmd); // Signalisieren Sie den anderen Thread oder was auch immer
};
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.