www.mikrocontroller.net

Forum: Compiler & IDEs Enums in Template-Klasse


Autor: RW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich denke, mein Problem erklärt sich von selbst an folgendem Code:
template<typename TPort>
class Led:
{
public:
  enum LedNr
  {
    LED0 = 0x01,
    LED1 = 0x02,
    LED2 = 0x04
  }

  void turnOn(uint8);
};


Led<PortA> led;
led.turnOn(Led::LED0); // wäre hübsch und logisch, funktioniert aber nicht
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.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht so?
template<typename TPort> class Led
{
public:
  enum LedNr
  {
    LED0 = 0x01,
    LED1 = 0x02,
    LED2 = 0x04
  };

  void turnOn(uint8);
};


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

Oder so?
template<typename TPort> class Led
{
public:
  enum LedNr
  {
    LED0 = 0x01,
    LED1 = 0x02,
    LED2 = 0x04
  };

  void turnOn(uint8);
};


Led<PortA> led;
led.turnOn(led.LED0);

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <iostream>

#include <stdint.h>


class LedBase
{
public:
  enum LedNr
  {
    LED0 = 0x01,
    LED1 = 0x02,
    LED2 = 0x04
  };

  virtual void turnOn( uint8_t ) = 0;

};

template<typename TPort>
class Led : public LedBase
{
public:

  void turnOn( uint8_t onoff )
  {
    std::cout << "Led::turnOn( onoff=" << int(onoff) << " )" << std::endl;
  }
};

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

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

Autor: RW (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.