Benutzer-Werkzeuge

Webseiten-Werkzeuge


skript:klassen-arduino

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
skript:klassen-arduino [2018/10/26 17:51]
d.golovko [1. Deklaration]
skript:klassen-arduino [2021/06/11 11:28] (aktuell)
d.golovko
Zeile 14: Zeile 14:
 class Song { class Song {
   public:   public:
-    Song(); // Konstruktor, muss noch mit Parametern versehen werden+    Song(int noteList[], int arraySize, int pinNumber); // Konstruktor
     void play(); // Methode zum Abspielen der Melodie     void play(); // Methode zum Abspielen der Melodie
   private:   private:
-    int * notes; // Noten-Frequenzen in Hz+    int *notes; // Noten-Frequenzen in Hz; ist ein Zeiger, da Array-Laenge noch nicht bekannt
     int arraySize; // Laenge des Noten-Arrays     int arraySize; // Laenge des Noten-Arrays
     int pin; // Piezo-Pin     int pin; // Piezo-Pin
Zeile 25: Zeile 25:
 <file cpp Song.cpp>​ <file cpp Song.cpp>​
 #include "​Song.h"​ #include "​Song.h"​
-Song::​Song() {+Song::Song(int noteList[], int arraySize, int pinNumber) {
   // TODO: Implementierung des Konstruktors fehlt   // TODO: Implementierung des Konstruktors fehlt
 } }
Zeile 37: Zeile 37:
  
 Ihr sieht oben, dass die Header-Datei zwei Blöcke hat, die mit ''​public''​ und ''​private''​ anfangen. Diese Schlüsselworte weisen auf die [[https://​de.wikipedia.org/​wiki/​Sichtbarkeit_(Programmierung)|Sichtbarkeit]] der Variablen und Funktionen hin. ''​Public''​ bedeutet, dass die Variable/​Funktion nur innerhalb der Klasse sichtbar ist, ''​protected''​ innerhalb der Klasse und ihrer Unterklassen,​ ''​public''​ überall. (Ähnliche Ebenen gibt es übrigens auch in Java.) Der Faustregel ist, die Sichtbarkeit möglichst begrenzt zu wählen. Die Begründung ist die gleiche wie bei globalen und lokalen Variablen: Je mehr Stellen haben Zugriff auf die Variable, desto mehr fehleranfällig ist der Code. Wir machen den Konstruktor und die Funktion ''​play()''​ ''​public'',​ damit wir darauf von unserem Haupt-Tab zugreifen können. Die beiden Variablen sind ''​private'',​ sie sollen nur innerhalb der Klasse verfügbar sein. Es ist üblich, in der Header-Datei den ''​public''​-Block ganz oben zu platzieren. ​ Ihr sieht oben, dass die Header-Datei zwei Blöcke hat, die mit ''​public''​ und ''​private''​ anfangen. Diese Schlüsselworte weisen auf die [[https://​de.wikipedia.org/​wiki/​Sichtbarkeit_(Programmierung)|Sichtbarkeit]] der Variablen und Funktionen hin. ''​Public''​ bedeutet, dass die Variable/​Funktion nur innerhalb der Klasse sichtbar ist, ''​protected''​ innerhalb der Klasse und ihrer Unterklassen,​ ''​public''​ überall. (Ähnliche Ebenen gibt es übrigens auch in Java.) Der Faustregel ist, die Sichtbarkeit möglichst begrenzt zu wählen. Die Begründung ist die gleiche wie bei globalen und lokalen Variablen: Je mehr Stellen haben Zugriff auf die Variable, desto mehr fehleranfällig ist der Code. Wir machen den Konstruktor und die Funktion ''​play()''​ ''​public'',​ damit wir darauf von unserem Haupt-Tab zugreifen können. Die beiden Variablen sind ''​private'',​ sie sollen nur innerhalb der Klasse verfügbar sein. Es ist üblich, in der Header-Datei den ''​public''​-Block ganz oben zu platzieren. ​
 +
 +Wenn in C++ Arrays als Parameter an eine Funktion übergeben werden, wird nur der Zeiger auf das erste Array-Element übergeben. D.h. die Funktion bekommt keine Kopie des ganzen Arrays, sondern nur die Adresse des ersten Elementes. Eine Lösung ist, die Array-Länge als einen weiteren Parameter (''​arraySize''​ in unserem Beispiel) zu übergeben. In der Liste der Membervariablen wird ebenso nur ein Zeiger ''​int *notes''​ verwendet, da die Deklaration eines Arrays ohne seiner Länge nicht möglich ist. 
  
 ====2. Implementierung==== ====2. Implementierung====
Zeile 47: Zeile 49:
 // Konstruktor;​ noteList: Notenabfolge,​ arraySize: Laenge des Noten-Arrays,​ pin: Piezo-Pin // Konstruktor;​ noteList: Notenabfolge,​ arraySize: Laenge des Noten-Arrays,​ pin: Piezo-Pin
 Song::​Song(int noteList[], int arraySize, int pinNumber) { Song::​Song(int noteList[], int arraySize, int pinNumber) {
-  ​for (int i 0; i < arraySize; ​i++) { +  ​this->​arraySize ​= arraySize;​ 
-    this->​notes[i] = noteList[i]; +  this->​notes = noteList;
-  }+
   this->​pin = pinNumber;   this->​pin = pinNumber;
 } }
 +
 //[...] //[...]
 </​file>​ </​file>​
- 
-Dementsprechend müssen wir die Konstruktordeklaration auch in Zeile 3 der Header-Datei ändern: \\ 
-''​Song(int noteList[], int arraySize, int pinNumber);''​ 
  
 Genauso wie in Java wird ''​this''​ benutzt, um auf die Instanz der Klasse (d.h. auf die gerade erzeugte Objekt vom Typ ''​Song''​) zu zeigen. Achtung: in C++ wird statt Punkt ein Pfeil verwendet.  ​ Genauso wie in Java wird ''​this''​ benutzt, um auf die Instanz der Klasse (d.h. auf die gerade erzeugte Objekt vom Typ ''​Song''​) zu zeigen. Achtung: in C++ wird statt Punkt ein Pfeil verwendet.  ​
Zeile 64: Zeile 63:
 #include "​Arduino.h"​ #include "​Arduino.h"​
 //[...] //[...]
 +// Spielt die Melodie ab
 void Song::​play() { void Song::​play() {
-  for (int i = 0; i < sizeof(notes) / sizeof(notes[0]); i++) { +  for (int i = 0; i < arraySize ​; i++) { 
-    tone(pin, notes[i]500); // jede Note spielt 0,5 Sekunde+    tone(pin, notes[i]); 
 +    delay(500);
   }   }
 +  noTone(pin);​
 } }
 //[...] //[...]
Zeile 79: Zeile 81:
 // Konstruktor;​ noteList: Notenabfolge,​ arraySize: Laenge des Noten-Arrays,​ pin: Piezo-Pin // Konstruktor;​ noteList: Notenabfolge,​ arraySize: Laenge des Noten-Arrays,​ pin: Piezo-Pin
 Song::​Song(int noteList[], int arraySize, int pinNumber) { Song::​Song(int noteList[], int arraySize, int pinNumber) {
-  ​for (int i 0; i < arraySize; ​i++) { +  ​this->​arraySize ​= arraySize;​ 
-    this->​notes[i] = noteList[i]; +  this->​notes = noteList;
-  }+
   this->​pin = pinNumber;   this->​pin = pinNumber;
 } }
Zeile 87: Zeile 88:
 // Spielt die Melodie ab // Spielt die Melodie ab
 void Song::​play() { void Song::​play() {
-  for (int i = 0; i < sizeof(notes) / sizeof(notes[0]); i++) { +  for (int i = 0; i < arraySize ​; i++) { 
-    tone(pin, notes[i]500); // jede Note spielt 0,5 Sekunde+    tone(pin, notes[i]); 
 +    delay(500);
   }   }
 +  noTone(pin);​
 } }
 </​file>​ </​file>​
Zeile 127: Zeile 130:
 </​file>​ </​file>​
  
-Der Konstruktor hier wird aufgerufen, bevor ''​setup()''​ anfängt. Das kann ungünstig sein im Fall, wenn der Konstruktor Parameter hat, deren Werte am Anfang des Programms noch nicht bekannt sind (z.B. wenn sie von Sensormessungen abhängen, die in ''​setup()''​ gemacht werden). Anders als in Java, können wir nicht einfach ''​Song mySong;''​ in Zeile 3 schreiben. Das daran, dass ''​mySong''​ eine Referenz ist, und Referenzen dürfen nicht gleich NULL sein. +Der Konstruktor hier wird aufgerufen, bevor ''​setup()''​ anfängt. Das kann ungünstig sein im Fall, wenn der Konstruktor Parameter hat, deren Werte am Anfang des Programms noch nicht bekannt sind (z.B. wenn sie von Sensormessungen abhängen, die in ''​setup()''​ gemacht werden). Anders als in Java, können wir nicht einfach ''​Song mySong;''​ in Zeile 3 schreiben. Das liegt daran, dass ''​mySong''​ eine Referenz ist, und Referenzen dürfen nicht gleich NULL sein. 
  
 <​note>​ <​note>​
skript/klassen-arduino.1540569076.txt.gz · Zuletzt geändert: 2018/10/26 17:51 von d.golovko