Forum: PC-Programmierung enum class - Kapselung ?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Veit D. (devil-elec)


Lesenswert?

Hallo,

hängt zwar mit einem Arduino Core Package zusammen, dass eigentliche 
Problem bzw. Frage dreht sich dennoch um C++ unabhängig von Arduino, 
deshalb frage ich mal hier.

Im verwendeten DxCore Package für AVRxDB Controller ist bspw. der Name 
B1 schon definiert
1
#define B1 1

Jetzt wollte ich ein enum anlegen mit Namen für meine Sensor Boards.
1
enum class HallSensorName {A1, B1, B2, C1, C2, C3, D1, D2, D3, E1, F1, NumberOfSensors};
2
3
bzw.
4
5
namespace HallSensoren {
6
  enum class HallSensorName {A1, B1, B2, C1, C2, C3, D1, D2, D3, E1, F1, NumberOfSensors};
7
}
Egal ob ich enum class oder zusätzlich in namespace 'HallSensoren' 
einkapsel erhalte ich
1
error: expected identifier before numeric constant
2
#define B1 1

Was ich nicht verstehe, weil class und namespace schränken doch die 
Sichtbarkeit ein. Es dürfte doch zu keinem Konflikt kommen. Hängt das 
mit dem #define und dem Präprozessor zusammen? Wenn ja, gibt es eine 
Lösung ohne das ich meine 'Enumeratoren' verstümmeln muss?

von Sebastian W. (wangnick)


Lesenswert?

Veit D. schrieb:
> Hängt das mit dem #define und dem Präprozessor zusammen?

Ja. Der Präprozessor ersetzt rein textuell.

Veit D. schrieb:
> Wenn ja, gibt es eine Lösung ohne das ich meine 'Enumeratoren' verstümmeln muss?
1
#undef B1

LG, Sebastian

von Oliver S. (oliverso)


Lesenswert?

#define stammt aus dem Pleistozän der Programmiersprache. Der 
Preprozessor ersetzt damit stumpf die eine Zeichenkette mit der anderen, 
egal, was da für neuzeitliche C++-Spielereien drum herum stehen.

Es hilft nix, B1 kannst du dein enum nicht nennen, wenn du auch das per 
define definierte brauchst. Wenn nicht, hilft ein an strategisch 
passender Stelle platziertes #undef.

Oliver

von Veit D. (devil-elec)


Lesenswert?

Hallo,

alles klar, Danke Euch.

Beitrag #7511627 wurde vom Autor gelöscht.
von Rolf M. (rmagnus)


Lesenswert?

Veit D. schrieb:
> Was ich nicht verstehe, weil class und namespace schränken doch die
> Sichtbarkeit ein.

Die Sichtbarkeit des enums ja, aber die des #define nicht.
Aus:
1
#define B1 1
2
3
enum class HallSensorName {A1, B1, B2, C1, C2, C3, D1, D2, D3, E1, F1, NumberOfSensors};

macht der Präprozessor erst mal:
1
enum class HallSensorName {A1, 1, B2, C1, C2, C3, D1, D2, D3, E1, F1, NumberOfSensors};

Und das bekommt dann der eigentliche Compiler zu Gesicht. Der kann aber 
mit der numerischen Konstanten 1 als Name eines Enum-Elements nichts 
anfangen und will einen Identifier haben, wie auch die Fehlermeldung ja 
sagt.
Und das passiert nicht nur bei der Definition, sondern auch bei jeder 
Anwendung von B1.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

genauso hatte/habe ich es verstanden. Danke auch dir.

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Wenn ja, gibt es eine
> Lösung ohne das ich meine 'Enumeratoren' verstümmeln muss?

Herzlichen Glückwunsch: Du bist nun über einen der beiden Hauptgründe 
(un-scoped, un-typed) gestolpert, warum man den Präprozessor besser 
nicht (so unbedacht) einsetzt.

Die Lösung wurde ja schon genannt.

: Bearbeitet durch User
von Manfred M. (bittbeisser)


Lesenswert?

Versuche doch mal dein enum wie eine eigene Classe zu behandeln. Bei mir 
funktioniert folgendes
1
class
2
Read_File {
3
  public:
4
    enum    cb_reason { none, new_object, new_data, end_object }; // access with: Read_File::xxx
5
...
und dann der Zugriff, etwa so:
1
...
2
    Read_File::cb_reason reason = fileloader->reason();
3
...
4
    switch( reason ) {
5
        case Read_File::new_object:
6
            obj_ptr = mwp->catalog->new_object();
7
            break;
8
...
Da wird in einer Callback Funktion der Grund für den Callback 
ausgewertet.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich vermute du vergisst den allmächtigen Präprozessor. Ich hatte mich 
entschieden das ich die Enumeratoren anders benannt habe. Man muss es 
nicht unnötig kompliziert machen. ;-)

von Rolf M. (rmagnus)


Lesenswert?

Veit D. schrieb:
> Ich hatte mich
> entschieden das ich die Enumeratoren anders benannt habe. Man muss es
> nicht unnötig kompliziert machen. ;-)

Letztendlich kam daraus ja daraus die Konvention, Alle Makro-Namen (und 
nur die und nichts anderes) komplett groß zu schreiben.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.