Hallo,
ich spiele gerade etwas rum und dabei bin ich an einen Punkt gekommen den ich mir nicht beantworten kann , darum die Frage hier.
Es gibt mehrere Instanzen von einer Klasse die letztlich mit einer for "each" Schleifen bearbeitet werden sollen. Ich hab dazu mal ein Blink Beispiel gemacht. siehe Setup und Loop.
/*Beispiel zu Classen in Verbindung mit
* for each Schleifen
*
*/
const byte ledpin[] = {2, 3, 4};
const uint32_t blinkzeit[] = {250, 500, 1000};
const byte anzahl = sizeof(ledpin) / sizeof(ledpin[0]);
class Blink {
private:
uint32_t altzeit;
bool zustand;
public:
byte pin;
uint32_t blinkzeit;
void begin(byte pn, uint32_t bz) {
blinkzeit = bz;
pin = pn;
pinMode(pin, OUTPUT);
}
void run() {
if (millis() - altzeit >= blinkzeit) {
altzeit = millis();
zustand = !zustand;
digitalWrite(pin, zustand);
Serial.print(pin), Serial.print(" ");
Serial.println(zustand);
}
}
};
Blink blinker[anzahl]; //Instanzen erstellen
void setup() {
// put your setup code here, to run once:
byte idx = 0;
for (auto &instanz : blinker) {
instanz.begin(ledpin[idx], blinkzeit[idx]);
idx++;
}
Serial.begin(115200);
Serial.print("Anzahl."); Serial.println(anzahl);
}
void loop() {
// put your main code here, to run repeatedly:
for (auto &instanz : blinker ) {
instanz.run();
}
}
Es geht mit nun um die Frage ob in der for each Schleife eine Kopie der Methode, bzw. mehrere Variable auf dem Stack abgelegt wird/werden oder wird da mit einem Zeiger gearbeitet. Ist da zwingend ein auto nötig ? Ein byte geht jedenfalls nicht deshalb vermute ich einen etwas größeren Speicherbedarf. Dann wäre eine normale for Schleife ja eventuell besser ?
Heinz
Kopien von Methoden gibt es nicht. Wenn dann wird das ganze Objekt kopiert. Du hast eine Referenz. Damit wird auch nichts kopiert. Das ist nicht anders wie bei einer Referenz als Funktionsparameter.
auto lässt den Datentyp vom Compiler bestimmen. Zwingend ist das nie. Man muss ihn dann halt selbst hinschreiben (in diesem Fall Blink). Das ist vor allem bei Templates schwierig.
pins brauchen vermutlich nicht zur Laufzeit geändert werden, das kann man imho const machen
wenn const --> InitialisierungsListe
auch einer Variable im Konstruktor kann man einen Default-Wert mitgeben
Die Blinkzeit will man vieleicht zur Laufzeit ändern. Dann macht man einen Setter.
Die Blinkzeit nicht public sein. Schreib dir einen Setter.
Und weils ichs auch erst gerade gelernt habe, die Variablen brauchst nicht zur Unkenntlichkeit verstümmeln um sie im Code verwenden zu können.
/*Beispiel zu Classen in Verbindung mit
for each Schleifen
*/
//const byte ledpin[] {2, 3, 4};
//const uint32_t blinkzeit[] {250, 500, 1000};
class Blink {
private:
const byte pin;
uint32_t blinkzeit;
uint32_t altzeit;
bool zustand;
public:
Blink(byte pin, uint32_t blinkzeit = 1000) : pin {pin}, blinkzeit {blinkzeit} {}
void begin() {
pinMode(pin, OUTPUT);
}
void setBlinkzeit(uint32_t blinkzeit)
{
this->blinkzeit = blinkzeit;
}
void run() {
if (millis() - altzeit >= blinkzeit) {
altzeit = millis();
zustand = !zustand;
digitalWrite(pin, zustand);
Serial.print(pin), Serial.print(" ");
Serial.println(zustand);
}
}
};
Blink blinker[]
{
{2, 250},
{3, 500},
{4}
}; //Instanzen erstellen
const byte anzahl = sizeof(blinker) / sizeof(blinker[0]);
void setup() {
// put your setup code here, to run once:
byte idx = 0;
for (auto &instanz : blinker) {
instanz.begin();
idx++;
}
Serial.begin(115200);
Serial.print("Anzahl."); Serial.println(anzahl);
}
void loop() {
// put your main code here, to run repeatedly:
for (auto &instanz : blinker ) {
instanz.run();
}
}
Hallo, @combie und @noiasca nochmals Danke Euch Beiden für die Beispiele, das mit dem Konstruktor war mir schon klar. Es wird halt bei vielen Parametern und vielen Instanzen schnell unübersichtlich finde ich ( in dem Beispiel ist das ja überschaubar) . Deshalb war mein Ansatz : Wie bekomme ich die erforderlichen Intitial-Parameter in viele Instanzen. So hab ich das ins Setup verlagert und zunächst mit einer normalen for... Schleife gemacht. Dann viel mir "for each" ein und so ist das entstanden.