Enum in Konstruktor, warum gehtz nicht?
-
Hallo,
class test { public: test(test::state ExecutingFunction) { if(ExecutingFunction==test::TEST1) pfunc=&test::test1; else pfunc=&test::test2; } void test1(){cout<<"TEST1"<<endl;} void test2(){cout<<"Test2"<<endl;} void Exec(){this->pfunc;} enum state { TEST1, TEST2 }; private: void (test::*pfunc)(); };was ist hier falsch?
Fehler: ) erwartetin der zeile wo der konstruktorkopf steht! (habe auch schon das test:: weggelassen, geht auch nicht!
Wie mache ich das denn richtig?
-
Versuch mal das enum vor dem Konstruktur zu packen
-
Knuddlbaer schrieb:
Versuch mal das enum vor dem Konstruktur zu packen
muh das geht!
da merkt man erstmal, das man garnix weiß!Ich würde trotzdem um aufklärung bitten!
-
Es war meinerseits mal geraten.
Generell kann der Compiler nur das verwenden, was er kennt.
Zu dem Zeitpunkt, an dem Du die enum verwendest, wurde diese
dem Compiler noch nicht gezeigt.Ich weiß nicht ob es spezielle Regeln innerhalb einer Klasse gibt.
Nun aber weiß der Compiler was test::TEST1 zu bedeuten hat, weil er es vor verwendung schon mal gesehen hat.
-
Ich weiß nicht ob es spezielle Regeln innerhalb einer Klasse gibt.
Ja, es gelten spezielle Regeln, bloss sind die für mich leider etwas verwirrend.
Funktionen darf man ja z.B. verwenden egal wo sie stehen... ein nested enum aber wieder nicht.
Wie's mit nested classes aussieht merk' ich mir auch nie, müsste ich jetzt ausprobieren.
-
Knuddlbaer schrieb:
Es war meinerseits mal geraten.
Generell kann der Compiler nur das verwenden, was er kennt.
Zu dem Zeitpunkt, an dem Du die enum verwendest, wurde diese
dem Compiler noch nicht gezeigt.Ich weiß nicht ob es spezielle Regeln innerhalb einer Klasse gibt.
Nun aber weiß der Compiler was test::TEST1 zu bedeuten hat, weil er es vor verwendung schon mal gesehen hat.Grundsätzlich sind Bezeichner (lexikalisch) vor ihrer Verwendung zu deklarieren. Das ist die Erste und wichtigste Regel dazu. Eine weitere - praktisch weniger bedeutsame - Regel bezieht auf die Deklaration von Bezeichnern in Klassen, die Bezeichner in einem äußeren Scope verdecken. Eine Umordnung von Deklarationen - beschränkt durch die erste Regel - darf hierbei nicht zu unterschiedlicher Semantik führen.
Drittens dürfen in der Definition von Funktionen (nicht in dem Teil, der zur Deklaration gehört - also ab dem { bzw. dem Funktions-try-Block bzw. der Initialisierungsliste von Konstruktoren), die in einer Klassendefinition definiert werden, alle Bezeichner, die dieser Klasse deklariert werden, verwendet werden, auch wenn diese lexikalisch erst danach erscheinen. Eine Klassendefinition wird also gewissermaßen 2mal geparst.
-
Exakt:
Deklarationen einer Klasse werden sequentiell (von oben nach unten) gelesen.
In den (inline-) Funktionsrümpfen können aber auch auf weiter unten stehende Deklarationen zugegriffen werden (Funktionsaufrufe, Enums, Members etc.), da diese erst nach dem Parsen der Klasse analysiert werden.
-
Knuddlbaer schrieb:
Es war meinerseits mal geraten.
Generell kann der Compiler nur das verwenden, was er kennt.
Zu dem Zeitpunkt, an dem Du die enum verwendest, wurde diese
dem Compiler noch nicht gezeigt.Ich weiß nicht ob es spezielle Regeln innerhalb einer Klasse gibt.
Nun aber weiß der Compiler was test::TEST1 zu bedeuten hat, weil er es vor verwendung schon mal gesehen hat.Ich bin ziemlich sicher, dass der Compiler Attribute und Funktionen der Klasse auch mit durchsucht, aber Typen müssen vorher bekannt - zumindestens muß dem Compiler ersichtlich sein, dass es sich um einen Typen handelt. So reicht eine Forwarddeklaration aus - wo möglich - allerdings braucht's die konkrete Typedefinition überall da, wo sie verwendet wird:
class B; // forward declaration (*) class A { public: enum enumT { YO, NO }; typedef int intT; A(enumT t) : myEnumT(t), myIntT(-1) {} // enumT hier schon bekannt A(intT t) : myEnumT(NO), myIntT(t) {} // intT hier schon bekannt A(B t); // B unbekannt - aber als Typ kenntlich durch (*) private: enumT myEnumT; intT myIntT; }; class B { public: int i; }; A::A(B t) : myEnumT(NO), myIntT(t.i) {} // B hier bekanntcamper kann das bestimmt noch exakter und besser formulieren...
EDIT: Oh, hat er schon ... naja, jetzt lösch' ich's nicht mehr.

Gruß,
Simon2.
-
Man kann noch etwas noch etwas präziser sein hinsichtlich dessen, wann genau ein Bezeichner deklariert ist (der sog. point of definition) - für unser Problem hier ist das eher bedeutungslos. Wichtig wid das mitunter bei enum-Definitionen und bei der Intialisierung von Variablen.
z.B.namespace A { char a = 5; namespace B { char a(a); // Initialisiert mit A::a, also 5 } namespace C { char a = a; // "Initialisiert" mit sich selbst, der Inhalt bleibt unbestimmt } } enum X { null, eins = null + 1 // Enumkonstanten sind ab dem folgenden Komma deklariert };