Forum: Compiler & IDEs Enums in Template-Klasse


von RW (Gast)


Lesenswert?

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.

von ... (Gast)


Lesenswert?

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);

von Klaus W. (mfgkw)


Lesenswert?

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
}

von RW (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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.

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.