Enums in Template-Klasse

Gast #1619381
Hallo,

ich denke, mein Problem erklärt sich von selbst an folgendem Code:
1
template<typename TPort>
2
class Led:
3
{
4
public:
5
  enum LedNr
6
  {
7
    LED0 = 0x01,
8
    LED1 = 0x02,
9
    LED2 = 0x04
10
  }
11

12
  void turnOn(uint8);
13
};
14

15

16
Led<PortA> led;
17
led.turnOn(Led::LED0); // wäre hübsch und logisch, funktioniert aber nicht
18
led.turnOn(Led<PortX>::LED0; // funktioniert, ist aber nicht hübsch

Ich möchte also von außerhalb auf die Enumeration zugreifen, ohne den 
Templateparameter anzugeben, weil ich den an anderen Stellen im Programm 
gar nicht wissen will. LedNr gehört logisch zu Led, darum will ich die 
Enumeration ungern ausgliedern. Zwar kann ich auch bei jedem Zugriff 
einen beliebigen (gültigen) Parameter angeben, aber das wäre auch 
hässlich.

Wie lässt sich dieses Problem elegant lösen?

Dankesehr schonmal.
Gast
Vielleicht so?
1
template<typename TPort> class Led
2
{
3
public:
4
  enum LedNr
5
  {
6
    LED0 = 0x01,
7
    LED1 = 0x02,
8
    LED2 = 0x04
9
  };
10

11
  void turnOn(uint8);
12
};
13

14

15
typedef Led<PortA> LedA;
16
LedA led;
17
led.turnOn(LedA::LED0);

Oder so?
1
template<typename TPort> class Led
2
{
3
public:
4
  enum LedNr
5
  {
6
    LED0 = 0x01,
7
    LED1 = 0x02,
8
    LED2 = 0x04
9
  };
10

11
  void turnOn(uint8);
12
};
13

14

15
Led<PortA> led;
16
led.turnOn(led.LED0);
Wenn die enum nicht zu den einzelnen Instanzen der template-Klasse
soll, sondern zu allen, dann gehört sie in eine gemeinsame Basisklasse.

Z.B. so:
1
#include <iostream>
2

3
#include <stdint.h>
4

5

6
class LedBase
7
{
8
public:
9
  enum LedNr
10
  {
11
    LED0 = 0x01,
12
    LED1 = 0x02,
13
    LED2 = 0x04
14
  };
15

16
  virtual void turnOn( uint8_t ) = 0;
17

18
};
19

20
template<typename TPort>
21
class Led : public LedBase
22
{
23
public:
24

25
  void turnOn( uint8_t onoff )
26
  {
27
    std::cout << "Led::turnOn( onoff=" << int(onoff) << " )" << std::endl;
28
  }
29
};
30

31
int main(int argc, char* argv[])
32
{
33
  typedef uint8_t PortA;
34

35
  Led<PortA> led;
36
  led.turnOn( LedBase::LED0 ); // funktioniert doch!
37
  led.turnOn( Led<PortA>::LED0 ); // funktioniert, ist aber nicht hübsch
38
}
Gast
Hallo,

vielen Dank für die Antworten.

@Klaus: Deine Variante ist hübsch. Wenn ich in die Basisklasse nur Enums 
schreibe, optimiert der Compiler sie vielleicht sogar weg. Dann wäre 
mein Problem elegant gelöst. Da ich auf einem Mikrocontroller arbeite, 
wollte ich virtuelle Methodenaufrufe nur sehr sparsam einsetzen.

@...: Auf die Idee, eine Enumeration über den Objektzeiger anstatt über 
den Klassennamen anzusprechen, bin ich noch gar nicht gekommen. Ich 
denke, das reicht mir schon aus.

Ciao.
Bei einer Klasse gibt es nichts weg zu optimieren.
Klassen als solche produzieren keinen Code, nur die Methoden.
Insofern kannst du ableiten soviel du willst.
Egal in welcher Klasse und wie sie definiert sind, sind enums
hinsichtlich des produzierten Codes nichts weiter als
schnöde Konstanten.

Auf einem MC würde ich aber in der Tat die virtuelle Methode
vermutlich rauswerfen, wenn du sie nicht brauchst und einfach
in den abgeleiteten Klassen neu definieren. Dann ist auch
mit Basisklasse kein zusätzlicher Overhead zu befürchten.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.