ich bin an sich kein Programmierer. Hab mir alles mögliche zu (u.a.) C++ quergelesen, um (u.a.) meinen Arduino zu programmieren. Klassen kannte ich schon ein bischen von Java.
Da mein Arduino-Code (LED-Sketch mit einigen switch-Anweisungen usw) mittlerweile über recht viele Seiten geht und reichlich unübersichtlich wird, würde ich einige Funktionen gerne auslagern.
Hab die Klassenerstellung und den Aufruf auch soweit hin bekommen - was mich allerdings stört, ist, das ich jedes mal ein Objekt erzeuge und damit hantiere. Da ich nur eine große LED-Stripe habe und die auch nur einen Wert annehmen wird, scheint die Erstellung von Objekten ein wenig über´s Ziel hinauszuschiessen.
Ich weiss, für OOP-Fans ist es der heilige Gral, und bei Autos, Tieren, Bankkunden und sonstwas ist es toll da man viele davon hat - meine Frage ist jedoch, ob ich auch ohne Objekte Aufrufe über Klassen hinbekommen kann.
Ich möchte bspw nur meinen Farbwechsel in eine Klasse auslagern, und dann einfach die HSV-Werte an eine Funktion (bzw Methode) übergeben, und die rauscht dann einmal durch und macht den Farbwechsel. Keine Objekte, keine Instanzen, kein sonstiger Luxus.
Das wäre meine erste Frage: gibt es da einen effizienteren Weg als über die Objekte zu arbeiten?
Das nächste ist, inwieweit ich den Code mit den Klassen aufblähe und was da so eure Erfahrungswerte sind - was wird mein Opfer sein um einen übersichtlichen Code zu haben? Macht das beim Arduino Sinn oder wühlt ihr euch einfach durch Seiten von Code?
Und dann noch folgendes: wenn ich ohne cpp arbeiten möchte (ich hätte in der .h-Klasse gern alles zusammen), wird dann der Code statt aufgerufen zu werden überall im Sketch hineinkopiert? Soll bei C++ ja so sein, hat man das am Arduino übernommen, sprich bin ich auf die cpp-Datei angewiesen damit der Code nicht komplett den Speicher sprengt?
Als OOP Fan, muss ich sagen, dass ich deine Fragen nicht verstehe.
Was ich aber sagen kann:
Im Grunde ist es egal, ob du den Code in einer *.h only hast, oder in eine *.cpp stopfst.
Irgendeine wundersame Codevermehrung entsteht dadurch nicht.
combie:
Als OOP Fan, muss ich sagen, dass ich deine Fragen nicht verstehe.
Inwiefern? Oder anders gesagt: was würde mir OOP in diesem Zusammenhang bringen können? Mir scheint OOP ist für meinen Einsatz nicht geeignet, also war der Gedanke das ich mir das Objekt (bzw den damit verbundenen belegten Speicher) dann vllt sparen kann.
combie:
Was ich aber sagen kann:
Im Grunde ist es egal, ob du den Code in einer *.h only hast, oder in eine *.cpp stopfst.
Irgendeine wundersame Codevermehrung entsteht dadurch nicht.
Das ist schon mal gut
ich beziehe mich dabei btw auf:
Es gibt einen minimalen Unterschied zwischen Methoden, die in einer Klasse nur deklariert und in einer Klasse vollständig definiert sind. Methoden, deren Implementation innerhalb einer Klasse liegt, heißen Inline-Methoden. Bei einem Aufruf einer Inline-Methode wird nicht der Code angesprungen, sondern der Compiler kopiert den Code der Methode jeweils an die Stellen der ausführbaren Datei, an denen die Methode verwendet wird. Inline-Methoden tauschen Speicherplatz gegen Geschwindigkeit ein: Es sind keine Sprünge nötig, um Code auszuführen. Dafür liegt der gleiche Code mehrfach in der ausführbaren Datei vor, so dass sich der Speicherbedarf der Anwendung erhöht.
Wieso soll es ein Problem sein ein Objekt einer Klasse zu erstellen? Das ist doch kein großer Aufwand. Und mehr Speicher als einzelne Variablen und Funktionen braucht ein Objekt auch nicht zwangsläufig. Höchstens wenn man sehr viele gekapselte Variablen mit Zugriffsmethoden anspricht. Das hängt von der Implementierung ab
Du kannst einen Sketch auch auf mehrere Tabs in der IDE aufteilen. Diese werden vor dem kompilieren zusammengefaßt und zusammen kompiliert. Achtung eine bestimmte Namensgebung ist wegen der Reihenfolge zu beachten. (welche das genau ist entzieht sich im Moment meinem Wissen).
Also in loop einen switch und dann springt er in eine Funktion die in einem anderen Tab liegt.
Methoden, deren Implementation innerhalb einer Klasse liegt, heißen Inline-Methoden.
Das hast du falsch verstanden.
Eine Methode wird zu einer inline Methode, wenn man das Attribut inline verwendet.
Hier ist noch so eine Stilblüte:
Sie sollten jedoch davon absehen und Eigenschaften und Methoden, die dem gleichen Zugriffsmechanismus unterliegen, in einem Block zusammenstellen, da dies die Übersicht erhöht.
Kein Wunder, dass du OOP für verachtenswert hältst.
Suche dir bitte eine seriösere Quelle.
So wird das nichts.
Was da gemeint sind dass Methoden die innerhalb eines Klassen-Körpers stehen (und nicht in einer seperaten .cpp Datei definiert werden) implizit inline sind. Das ist allerdings nicht sauber erklärt, weil es eben noch andere Möglichkeiten gibt inline Methoden zu erzeugen
Serenifly:
Das ist allerdings nicht sauber erklärt[...]
combie:
Suche dir bitte eine seriösere Quelle.
Alles klar, ist direkt mal aus den Lesezeichen geflogen
uwefed:
Du kannst einen Sketch auch auf mehrere Tabs in der IDE aufteilen. Diese werden vor dem kompilieren zusammengefaßt und zusammen kompiliert. Achtung eine bestimmte Namensgebung ist wegen der Reihenfolge zu beachten. (welche das genau ist entzieht sich im Moment meinem Wissen).
Also in loop einen switch und dann springt er in eine Funktion die in einem anderen Tab liegt.
Grüße Uwe
Das klingt exakt nach dem was ich suche
Edit: gerade mal geschaut, man kann die Tabs tatsächlich einfach xxx.ino benennen, und die werden dann alphabetisch (sprich aufsteigend nach dem / den Anfangsbuchstabe(n) ) zu einem Sketch zusammengefasst - ganz genau so brauche ich das.
uwefed:
Du kannst einen Sketch auch auf mehrere Tabs in der IDE aufteilen. Diese werden vor dem kompilieren zusammengefaßt und zusammen kompiliert. Achtung eine bestimmte Namensgebung ist wegen der Reihenfolge zu beachten. (welche das genau ist entzieht sich im Moment meinem Wissen).
Was passiert, wenn in der Arduino-IDE mehrere Tabs verwendet werden:
Grundsätzlich bekommen zusätzliche Tabs (STRG+Umschalt+N) ebenfalls die Endung .ino und werden im selben Ordner gespeichert, wie der „Haupt-Tab“.
Vor dem unmittelbaren Kompilieren werden alle Tabs in ein gemeinsames CPP-File kopiert und zwar zuerst der „Haupt-Tab“ und danach die Zusatz-Tabs in alfabetischer Reihenfolge.
Beispiel:
test.ino (der „Haupt-Tab“ – der Ordner heißt ebenfalls „test“)
aaa.ino (ein Zusatz-Tab)
nnn.ino (noch ein Zusatz-Tab)
zzz.ino (weiterer Zusatz-Tab)
Ganz oben fügt die IDE Prototypen der verwendeten Funktionen hinzu (zumindest wird das versucht und es funktioniert auch meist recht gut).
Die alfabetische Reihenfolge der Abarbeitung der Tabs ist zu bedenken, vor allem bei "komplexeren Konstrukten".
So sind globale Variable etwa nur „nachfolgenden“ Funktionen und in folgenden Tabs bekannt. Eventuell ist es auch sinnvoll sich selbst um Prototypen zu kümmern.
Achtung: Die IDE fügt einige zusätzliche Code-Zeilen ein. Die Aufteilung in einzelne Tabs sollte also an „günstigen“ Punkten erfolgen und nicht „irgendwo im Code“.
Wer ausführliche Meldungen einschaltet (Menü / Datei / Voreinstellungen / Ausführliche Warnungen während Kompilierung ANHAKEN), kann leicht herausfinden, wo die "zusammengesetzte" CPP-Datei liegt und sich diese mal ansehen. Das ist durchaus interessant.
Meist ist der Dateipfad etwa so:
C:\Users\theUserName\AppData\Local\Temp\arduino_build_xxxxxx\preproc\ctags_target_for_gcc_minus_e.cpp
bzw: ...\sketch\test.ino.cpp
uxomm:
Was passiert, wenn in der Arduino-IDE mehrere Tabs verwendet werden:
Das gilt aber nur, wenn die Dateien die Endung .ino haben. Man kann beim Erzeugen eines neuen Tabs ( ctrl-shift-N) auch eine .h oder .c/.cpp Datei erzeugen. Die erscheinen dann auch als Tab, werden aber nicht mit der .ino des Sketches zusammengefasst, sondern die .c/.cpp werden ganz 'klassisch' getrennt compiliert und erst der Linker baut das dann zusammen. Da muss dann aber - ebenfalls ganz 'klassich' - die .h Datei inkludiert werden ( mit "..." und nicht mit <...> )
Das hat dann aber noch nicht unbedingt mit OOP und Klassen zu tun