Wie übergibt man dem (struct) Konstrutor Defaultwerte ?

Hallo,

ich scheitere momentan daran dem Konstruktor Defaultwerte mitzugeben. Sodass man nicht bei jedem Objekt alles doppelt gemoppelt angegeben muss.

Angefangen habe ich damit.

struct t_blink
{                               // was benötigt man alles für ein zeitlich begrenztes LED blinken
  const byte pin_taster;
  const byte pin_led;
  const unsigned int interval;  // Zeit für das Blinkintervall
  bool state_taster;            // Status LOW/HIGH des Tasters merken (gedrückt/nicht gedrückt) LOW aktiv
  bool state_led;               // Status LOW/HIGH der LED merken (aus/ein)
  const unsigned int count;     // wie oft SOLL geblinkt werden
  unsigned int last_count;      // Zähler wie oft schon geblinkt wurde
  unsigned long last_ms;        // Zeit merken für das blinken
};

t_blink blinker[] = {           // Objekt blinker Array mit Initialisierung
   /*
   Taster-Pin,
   |  LED-Pin,
   |  |   Blinkintervall,
   |  |   |     Taster Zustand default,
   |  |   |     |     LED Zustand default,
   |  |   |     |     |   Blinkanzahl,
   |  |   |     |     |   |  letzter count default,
   |  |   |     |     |   |  |  last millis   */
  {2, 28, 200, HIGH, LOW, 5, 0, 0},  
  {3, 29, 400, HIGH, LOW, 5, 0, 0},
  {4, 30, 600, HIGH, LOW, 5, 0, 0},
  {5, 31, 800, HIGH, LOW, 5, 0, 0}
};

Dann habe ich einen Konstruktor hinzugefügt.

struct t_blink
{                               // was benötigt man alles für ein zeitlich begrenztes LED blinken

  t_blink (byte pTASTER, byte pLED, unsigned int interv, bool sTASTER, bool sLED, unsigned int counter, unsigned int last_counter, unsigned long last_millis) :
          // Initialisierungsliste
          pin_taster (pTASTER),
          pin_led (pLED),
          interval (interv),          // Zeit für das Blinkintervall
          state_taster (sTASTER),     // Status LOW/HIGH des Tasters merken (gedrückt/nicht gedrückt) LOW aktiv
          state_led (sLED),           // Status LOW/HIGH der LED merken (aus/ein)
          count (counter),            // wie oft SOLL geblinkt werden
          last_count (last_counter),  // Zähler wie oft schon geblinkt wurde
          last_ms (last_millis)       // Zeit merken für das blinken
  {}
  const byte pin_taster;
  const byte pin_led;
  const unsigned int interval;  // Zeit für das Blinkintervall
  bool state_taster;            // Status LOW/HIGH des Tasters merken (gedrückt/nicht gedrückt) LOW aktiv
  bool state_led;               // Status LOW/HIGH der LED merken (aus/ein)
  const unsigned int count;     // wie oft SOLL geblinkt werden
  unsigned int last_count;      // Zähler wie oft schon geblinkt wurde
  unsigned long last_ms;        // Zeit merken für das blinken
 
};

t_blink blinker[] = {           // Objekt blinker Array mit Initialisierung
   /*
   Taster-Pin,
   |  LED-Pin,
   |  |   Blinkintervall,
   |  |   |     Taster Zustand default,
   |  |   |     |     LED Zustand default,
   |  |   |     |     |   Blinkanzahl,
   |  |   |     |     |   |  letzter count default,
   |  |   |     |     |   |  |  last millis   */
  {2, 28, 200, HIGH, LOW, 5, 0, 0},  
  {3, 29, 400, HIGH, LOW, 5, 0, 0},
  {4, 30, 600, HIGH, LOW, 5, 0, 0},
  {5, 31, 800, HIGH, LOW, 5, 0, 0}
};

Was ich möchte ist bei der Objekterstellung die letzten 5 Parameter weglassen wenn nicht abweichend von default.
Also so würde ich es mir wünschen.

t_blink blinker[] = {           // Objekt blinker Array mit Initialisierung
   /*
   Taster-Pin,
   |  LED-Pin,
   |  |   Blinkintervall,
   |  |   |      
  {2, 28, 200},  
  {3, 29, 400},
  {4, 30, 600, , , 88},  // hier abweichend von default
  {5, 31, 800}
};

und das restliche (HIGH, LOW, 5, 0, 0) im Konstruktor als default übergeben.
Wie geht das? Ich weiß nicht weiter.

  t_blink (byte pTASTER, byte pLED, unsigned int interv, bool sTASTER = HIGH, bool sLED = LOW, unsigned int counter = 5, unsigned int last_counter = 0, unsigned long last_millis = 0) :

sollte gehen, aber {4, 30, 600, , , 88},  // hier abweichend von default geht nicht.

Hi

Bei Funktionen gibst Du

bool funktion(byte pin,byte startwert=200) { ... }

einen Default-Wert per = an.
Wenn der Wert nicht mit übergeben wird, ist Er Standard - sonst wird der übergebene Wert benutzt.
Da eine Methode 'nur' eine Funktion in einer Klasse ist - könnte Das auch da funktionieren.

Da Du aber wesentlich fitter in der Materie bist, als ich, wirst Du Das wohl bereits durch haben.

MfG

  1. Du kannst defaultwerte angeben, wie bei anderen Funktionen auch.
  2. Du kannst verschiedene Konstruktoren, mit unterschiedlichen Signaturen, erfinden.

Noch ein Tip: die Namen der Variablen und der Konstruktor-Parameter können identisch sein. Der Compiler kann das auflösen

Hallo,

ich Rindvieh wollte den Defaultwert immer in die Klammern der Initialisierungsliste schreiben. :grinning:
Danke Euch.

Momentan benötige ich noch die zusätzliche Gedankenstütze was was ist und an wem es zugewiesen wird. Da die Namen eh keine Rolle spielen habe ich diese eingekürzt, sonst wird der Konstruktor ellenlang. :wink:

Aktueller Stand - Reihenfolge minimal geändert. Dann mach ich mich an verschiedene Konstruktoren ran.

struct t_blink
{                               // was benötigt man alles für ein zeitlich begrenztes LED blinken
  t_blink (byte _A, byte _B, unsigned int _C, unsigned int _D, bool _E = HIGH, bool _F = LOW, unsigned int _G = 0, unsigned long _H = 0) :
          // Initialisierungsliste
          pin_taster (_A),
          pin_led (_B),
          interval (_C),          
          count (_D),   
          state_taster (_E),    
          state_led (_F),          
          last_count (_G),     
          last_ms (_H)             
  {}
  const byte pin_taster;
  const byte pin_led;
  const unsigned int interval;  // Zeit für das Blinkintervall
  const unsigned int count;     // wie oft SOLL geblinkt werden
  bool state_taster;            // Status LOW/HIGH des Tasters merken (gedrückt/nicht gedrückt) LOW aktiv
  bool state_led;               // Status LOW/HIGH der LED merken (aus/ein)
  unsigned int last_count;      // Zähler wie oft schon geblinkt wurde
  unsigned long last_ms;        // Zeit merken für das blinken
};

t_blink blinker[] = {           // Objekt blinker Array mit Initialisierung
   /*
   Taster-Pin,
   |  LED-Pin,
   |  |    Blinkintervall,
   |  |    |   Blinkanzahl,
   |  |    |   |    Taster Zustand default,
   |  |    |   |    |    LED Zustand default,
   |  |    |   |    |    |   letzter count default,
   |  |    |   |    |    |   |   last millis         */
  {2, 28, 200, 8},  
  {3, 29, 400, 7},
  {4, 30, 600, 6, HIGH, LOW, 0, 0},   // die letzten vier Parameter muss man nicht mehr angeben, weil es im Konstruktor Defaultwerte gibt
  {5, 31, 800, 5}
};

Da die Namen eh keine Rolle spielen habe ich diese eingekürzt, sonst wird der Konstruktor ellenlang.

Wenn jemand anderes deinen Code liest und verstehen will ist das schon wichtig richtige Namen zu haben

Es spielt auch eine Rolle für Dokus oder wenn man eine richtige IDE hat (siehe z.B. Intellisense bei Visual Studio). Da sieht man anhand der Paramter-Namen was man übergeben muss

Doc_Arduino:
Da die Namen eh keine Rolle spielen habe ich diese eingekürzt, sonst wird der Konstruktor ellenlang. :wink:

Viele Wege führen nach Rom, diesen habe ich von combie abgeschaut, "spart" Namen:

Blumen(const byte messPin, const byte relaisPin, const unsigned int trockenWert, const unsigned long messIntervall, const unsigned long giessIntervall, const unsigned long nachgiessenIntervall):
    messPin(messPin), relaisPin(relaisPin), trockenWert(trockenWert), messIntervall(messIntervall), giessIntervall(giessIntervall), nachgiessenIntervall(nachgiessenIntervall), messwert(0), vorhin(0), intervall(0), zaehler(0), schritt(0) {}

Ausführlich hier: Wieder bewässerung - #53 by agmue - Deutsch - Arduino Forum

@ Serenifly: okay verstehe, welchen von beiden sieht man mit Intellisense? Den Membernamen oder den Konstruktornamen? Ich nehme mal an man sieht den Konstruktorname?

@ Whandall & agmue: Aha Effekt. Als ich vorhin versuchte den Defaultwert in der Initialisierungsliste anzugeben hatte ich vergessen die Parameter aus dem Konstruktor rauszunehmen. Der kleine aber feine Unterschied.

Wenn man mit der Vielfalt der Möglichkeiten experimentiert wird man förmlich erschlagen. :slight_smile:

Whandalls Version hat Defaultwerte und man kann wenn man möchte einen anderen Wert bei Objekterstellung angeben.
Das die ist flexibelste Variante für alle Fälle. :slight_smile:

Die andere Variante mit mehreren Konstruktoren hat je nachdem feste Defaultwerte die man bei Objekterstellung nicht angeben kann. Das ist der Unterschied den ich erkenne. Außer man greift später von außen darauf zu und manipuliert. Was ich auch mache aber jetzt mit sicheren Anfangswert der bei Objekterstellung nicht versaut werden kann. Die Reihenfolge der Member musste ich auch ändern sonst geht das mit dem Konstruktor nicht auf.

struct t_blink
{                               // was benötigt man alles für ein zeitlich begrenzten LED Blinker  
  const byte pin_taster;        // Member Variablen ...
  const byte pin_led;
  const unsigned int interval;  // Zeit für das Blinkintervall
  const unsigned int count;     // wie oft SOLL geblinkt werden
  bool state_taster;            // Status LOW/HIGH des Tasters merken (gedrückt/nicht gedrückt) LOW aktiv
  bool state_led;               // Status LOW/HIGH der LED merken (aus/ein)
  unsigned long last_ms;        // Zeit merken für das blinken
  unsigned int last_count;      // Zähler wie oft schon geblinkt wurde
  
  // Default Konstruktor
  t_blink (byte pin_taster, byte pin_led, unsigned int interval, unsigned int count) :
      // Initialisierungsliste
      pin_taster (pin_taster),
      pin_led (pin_led),
      interval (interval),         
      count (count),  
      state_taster (HIGH),    // Defaultwerte ...
      state_led (LOW),
      last_ms (0),
      last_count (0)             
  {}
  
  // weiterer Konstruktor bei Befarf
  t_blink (byte pin_taster, byte pin_led, unsigned int interval, unsigned int count, bool state_taster, bool state_led) :
      // Initialisierungsliste
      pin_taster (pin_taster),
      pin_led (pin_led),
      interval (interval),         
      count (count),   
      state_taster (state_taster),   
      state_led (state_led),  
      last_ms (0),                  // Defaultwerte ...
      last_count (0)          
  {}
  
};

t_blink blinker[] = {           // Objekt blinker Array mit Initialisierung
   /*
   Taster-Pin,
   |  LED-Pin,
   |  |    Blinkintervall,
   |  |    |   Blinkanzahl,
   |  |    |        Taster Zustand default HIGH,
   |  |    |   |    |     LED Zustand default LOW
   |  |    |   |    |     |                        */
  {2, 28, 200, 8},                    // nutzt Default Konstruktor
  {3, 29, 400, 7},
  {4, 30, 600, 6, HIGH, HIGH},        // nutzt anderen Konstruktor, LED ist nach Reset erstmal an
  {5, 31, 800, 5}           
};

Fettes Danke an alle. Der Tag ist erfolgreich. :slight_smile:

Doc_Arduino:
@ Serenifly: okay verstehe, welchen von beiden sieht man mit Intellisense? Den Membernamen oder den Konstruktornamen? Ich nehme mal an man sieht den Konstruktorname?

Es geht um die Namen der Parameter

Arduino1.jpg
Arduino2.jpg

Du siehst also was die Parameter bedeuten ohne unbedingt in eine Doku zu schauen

Wobei das auch in der Arduino Software bei dem Beispiel nicht ganz schön ist:

    void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
    void begin(unsigned long, uint8_t);

Für den Konstruktor mit einem Parameter sieht man das "baud". Bei dem mit zwei fehlt es

Du hast hattest zwar Namen (nur in einem Header kann man sie ganz weglassen) aber wenn die kryptisch sind bringt es auch nichts

Hallo,

verstehe. Kurze und dennoch aussagekräftige Namen sind eines meiner ungelösten Probleme ... :slight_smile:

Meins auch!
Das Problem persistiert.