Aufzählungstypen

coder111

Mitglied
Hallo,
ich hätte ein paar Fragen zur Enumeration.

1) Ist "mischung" eine Variable vom Typ Palette?
enum class Palette { weiss = 0, grau = 1, braun = 2, amber = 4, lila = 8 } mischung;

2) Wann befinden Sich zwei Enumerationen im selben Gültigkeitsbereich?

3) Warum entsteht ein Compileerror, bei diesem Code?

C++:
enum class Farbtyp {rot,gruen,blau,gelb};
    Farbtyp f=rot;

Wenn ich class weglasse, dann hab ich keinen Compileerror.

C++:
enum  Farbtyp {rot,gruen,blau,gelb};
    Farbtyp f=rot;
 

sheel

I love Asm
Hi

Zuerst zum Scope von "normalen" Variablen generell: Es orientiert sich immer an den {}
C++:
int a = 1;
//hier gibt es a
int main()
{
    //hier gibt es a
    int b = 2;
    //hier gibt es a und b
    if(b==2)
    {
        //hier gibt es a und b
        int c=3;
        //hier gibt es a und b und c
    }
    //hier gibt es a und b
}
//hier gibt es a
(Die Wirklichkeit ist komplizierter, mit static, inline, extern, new und Pointern usw.usw.)

Folge 1: Variablen können natürlich nur dort verwendet werden, wo es sie gibt. Egal obs um Eingaben, Ausgaben, Rechnen oder sonstwas geht, eine nichtexistierende Variable bringt Compilerfehler.
Folge 2: Nach zB. "int c=3" darf man nicht sofort "int c=99" schreiben, weil es schon ein a gibt. ("c=99;" ist ok, Zuweisung, aber ein komplett neues c machen geht da nicht). Nach der nächsten }, da wo es wieder nur a und b gibt, wäre ein neues c aber ok; das alte gibts dort eben nicht mehr.
Folge 3: Shadowing: Wie gerade gesagt darf es nicht zwei Variablen geben, deren Scope sich überlappt. C und C++ (und auch einige andere Sprachen) haben aber auch ein Feature :)D), dass äußere Variablen doch von inneren überdeckt werden können.
C++:
int a = 1;
a = 2;
int a = 3;
a = 4;
Wie bei c oben geht das nicht, zwei a ist eins zu viel. Folgendes geht aber:
C++:
int a = 1;
//a ist 1
a = 2;
//a ist 2
{
    int a = 3;
    //ein zweites a hat das äußere "verdeckt", a ist 3
    a = 4;
    //a ist 4
}
//hier ist wieder das alte a aktiv, a ist 2

...

Damit zur Frage 2 als Erstes: Gleich wie oben. Ein enum (samt Typname und Namen der Werte innen) verhalten sich wie die gezeigten ints.

Frage 1: Ja.
C++:
enum class Palette { weiss = 0, grau = 1, braun = 2, amber = 4, lila = 8 } mischung;
ist gleichwertig wie
C++:
enum class Palette { weiss = 0, grau = 1, braun = 2, amber = 4, lila = 8 };
Palette mischung;
Sowas geht auch mit struct, class, union...

Frage 3: Gegenfrage: Soll es jetzt ein enum oder enumclass werden? Das sind zwei verschiedene Sachen.
(Die Infos oben gelten für beide).
(Hier ist es zwar klar, aber bitte trotzdem immer Compilerfehler auch dazuschreiben).
 

coder111

Mitglied
Hallo sheel,
vielen Dank für deine Hilfe :)

Ich weiß jetzt nicht was der Unterschied zwischen enum und enum class ist?
Aber ich weiß jetzt wie der Compileerror verschwindet:

Code:
enum class Farbtyp {rot,gruen,blau,gelb};
    Farbtyp f = Farbtyp::rot;
 

sheel

I love Asm
Mit dem "alten" einfachen enum kann man uA. die folgenden Sachen machen (und nicht machen):

C++:
enum e { a, b, c, d=8 };
//Hinweis: Weil nicht speziell angegebenen entsprechen
//a b c 0 1 2. d ist aber eben nicht 3 sondern 8

e e1; //Variable vom Typ e;
e1 = b; //ist ist jetzt 1

e e2;
e2 = e::b; //Ähnlich wie oben, aber nochmal betonen dass b zu e gehört.
//Macht keinen wirklichen Unterschied, außer für die Verständlichkeit
//für Menschen

int i; //Typ int, nicht e
i = b; //auch i ist jetzt 1

int b; //Fehler, weil es den Namen b (in dem Scope hier) schon gibt.
//Obwohl b "nur" ein Teil von e ist. Kann ziemlich nerven, die Namen
//nicht mehr zur Verfügung zu haben.
Oder anders gesagt,
C++:
enum e { a, b, c, d=8 };
wirkt vergleichbar wie
C++:
enum e { a, b, c, d=8 };
int a = 0;
int b = 1;
int c = 2;
int d = 8;
(natürlich sind a b c d keine vollen Variablen, denen man was zuweisen kann und so, aber was den Wert und Scope angeht...)

Mit enum class (das es noch nicht so lang wie enum gibt) ist alles etwas strenger: Keine Scope-"Infektion" und nicht so frei mit int vermischbar.

C++:
enum class e { a, b, c, d=8 };

e e1;
e1 = e::b; //ist 1, wie mit den normalen enum auch

e e2;
e2 = b; //Fehler, was ist b? e::b gibts, aber diesmal ist b selber nichts

int i;
i = e::b; //Fehler, e::b ist ein Wert von e und kein int.
//...
//Mit alten enums könnte man enum tier {hund, katze} machen
//und dann ausrechnen, dass die Wurzel von katze wieder katze
//ergibt (Wurzel 1 == 1). Hier wehrt der Typ sich praktisch dagegen,
//missbraucht zu werden. e-Werte gehören in Variablen vom Typ
//e (und die Wurzelfunktion will keine e). Die Zahl als int
//rauszubekommen geht schon noch, aber das muss man
//deutlicher hinschreiben: i=(int)e::b;

int b; //Ok, weil es ja noch kein b gibt.
 
Zuletzt bearbeitet:

coder111

Mitglied
Danke, deine Antworten sind immer verständlich und ausführlich :)
Aber warum ist hier die Variable a vom Typ int im Scope, obwohl "a" außerhalb der Blockklammern steht?

C++:
enum e { a, b, c, d=8 };
    int a = 0;
 

sheel

I love Asm
Ist einfach eine Ausnahme von der Regel, weil so vom Erfinder festgelegt.

Seit es enum class gibt seh ich überhaupt keinen Grund mehr, das normale enum überhaupt zu verwenden. Mit enum class ist die Scopesache wie sonst auch immer...