Hallo Ich möcht gern einen neue Class mit einem Array anlegen! Aber leider geht es nicht ! Was mache ich falsch ? ----------------------------------------------------------------- so würde ich das Array ohne Class deklarieren ! byte INPUT_ARRAY [] = { 0,0,0 }; ----------------------------------------------------------------- in der Class geht das aber nicht warum ? Beispiel.h Datei class BeispielClass { public: BeispielClass(); byte INPUT_ARRAY[]; private: }; Beispiel.cpp Datei BeispielClass::BeispielClass() { // Initialisierung alle drei Werte auf Null INPUT_ARRAY [] = { 0,0,0 }; } Danke für eure Hilfe MFG Michael
:
Verschoben durch User
Michael K. schrieb: > Was mache ich falsch ? es geht nicht, dann woher soll denn die Klasse ihre Größe kennen? Man müsste mit Templates oder mit stl-Listen arbeiten.
wie würde so was aussehen ? geht das nicht einfacher ? Gruß Michael
Zum Beispiel so: Deklaration im Klassenheader:
1 | static byte INPUT_ARRAY[]; |
Definition:
1 | byte BeispielClass::INPUT_ARRAY[] = |
2 | {
|
3 | 0, 0, 0, |
4 | }
|
:
Bearbeitet durch User
J. F. schrieb: > Zum Beispiel so: naja, ein static ist bestimmt nicht das was er will. @Michael K. soll jedes Objekt die gleiche Länge haben? geht es um einen kleinen µC oder eine PC?
Peter II schrieb: > J. F. schrieb: >> Zum Beispiel so: > > naja, ein static ist bestimmt nicht das was er will. Überlese ich irgendwas, das er diese Möglichkeit ausschließt?
http://stackoverflow.com/questions/478967/c-array-member-of-constant-length-initialisation-of J. F. schrieb: >> naja, ein static ist bestimmt nicht das was er will. > Überlese ich irgendwas, das er diese Möglichkeit ausschließt? Aua.
Michael K. schrieb: > Hallo > > Ich möcht gern einen neue Class mit einem Array anlegen! > > Aber leider geht es nicht ! > Was mache ich falsch ? > ----------------------------------------------------------------- > so würde ich das Array ohne Class deklarieren ! > > > byte INPUT_ARRAY [] = { 0,0,0 }; > > ----------------------------------------------------------------- > in der Class geht das aber nicht warum ? > > Beispiel.h Datei > > class BeispielClass > { > public: > BeispielClass(); > > byte INPUT_ARRAY[]; > > private: > > }; > > Beispiel.cpp Datei > > BeispielClass::BeispielClass() > { > // Initialisierung alle drei Werte auf Null > > INPUT_ARRAY [] = { 0,0,0 }; > } > Ab C++11 gehen auch in-class-initializer also: class XYZ { uint8_t buffer[] = {1, 2, 3}; }
Di P. schrieb: > Lösung über die initializer-list: nur ein Teil der Lösung - mit einem C-Array geht es auch mit der initializer-list nicht.
Di P. schrieb: > Bei mir kompiliert und läuft es, so wie im Link. da ist ja auch kein C Array mehr drin.
Peter II schrieb: > Di P. schrieb: >> Bei mir kompiliert und läuft es, so wie im Link. > > da ist ja auch kein C Array mehr drin. was denn sonst?
Di P. schrieb: >> da ist ja auch kein C Array mehr drin. > > was denn sonst? oh sorry, ich dachte da steht ein std::array
Da die Anfrage in dieser Liste auftaucht, gehe ich davon aus, dass es nicht für eine MCU als bare-metal C++ gedacht ist. Dann hättest Du also ein libstc++ zur Verfügung. In dem Fall gibt es gar keine Berechtigung für ein rohes C-Array im C++-Code. Dann nimmt man ein std::array template: http://coliru.stacked-crooked.com/a/66ee3d405f51f2a8 Sollte es auf einer MCU laufen ohne libstdc++, so kannst Du erstmal std::array nicht verwenden: dann schreibst Du Dir dieses Template selbst. Solltest Du das nicht können, solltest Du erst einmal ohne MCU C++ lernen. Die schlechteste Alternative wäre, trotzdem ein rohes C-Array zu verwenden.
Michael K. schrieb: > so würde ich das Array ohne Class deklarieren ! > > byte INPUT_ARRAY [] = { 0,0,0 }; Abgesehen davon, dass dann ein Typ namens "byte" definiert werden muss und Namen komplett in Großbuchstaben eigentlich eher für Makros reserviert werden sollten, passt das so. Die Größe des Arrays wird in dem Fall aus dem direkt folgenden Initialisierer automatisch extrahiert. > Beispiel.h Datei > > class BeispielClass > { > public: > BeispielClass(); > > byte INPUT_ARRAY[]; Hier fehlt die Größe. Ein Array muss immer eine Größe haben. Sonst weiß der Compiler nicht, wieviel Platz dafür (und in diesem Fall dann auch für ein Objekt vom Typ BeispielClass) benötigt wird. Da du nicht direkt einen Initialisierer dahinterschreiben kannst, musst du die Größe explizit angeben: byte INPUT_ARRAY[3]; > // Initialisierung alle drei Werte auf Null Wie "alle drei"? Oben hast du versucht, ein Array zu definieren, das gar keine Größe hat. > INPUT_ARRAY [] = { 0,0,0 }; Das ist eine Zuweisung, keine Initialisierung - allerdings müssen die eckigen Klammern da weg, außerdem kann man in C++ arrays nicht an andere zuweisen.
Mit C++11 geht sowas: Siehe angehängte Dateien Allerdings bekomme ich hier mit g++ eine Warnung, die ich im Moment noch nicht so recht nachvollziehen kann. Beispiel.cpp: In constructor 'BeispielClass::BeispielClass()': Beispiel.cpp:5:10: warning: unused variable 'INPUT_ARRAY' [-Wunused-variable] byte INPUT_ARRAY[3] { 0,0,0 }; ^ Wieso jetzt unbenutzte Variable?
Weil INPUT_ARRAY im ctor eine LOKALE Variable ist!
:
Bearbeitet durch User
Äh, ja. Zu wenig Kaffee ;-) Aber sowas im Konstruktor z.B. geht auch nicht: this->INPUT_ARRAY = { 0,0,0 }; Kann C++11 das vielleicht nur für std::array Typen? Oder auch für normale C Arrays?
Mark B. schrieb: > Aber sowas im Konstruktor z.B. geht auch nicht: > > this->INPUT_ARRAY = { 0,0,0 }; was auch klar ist, denn wie soll man die größe der Kasse nur mit Hilfe der Header-Datei erkennen - und das braucht zwingend der Compiler.
Nein! Bitte erst mal den Unterscheid zwischen Kopierzuweisung und Initialisierung lernen! Sorry, aber da fehlen die absoluten Basics. Es gibt wunderbare Bücher, etc. zu C++ ;-)
Wilhelm M. schrieb: > Es gibt wunderbare Bücher, > etc. zu C++ ;-) Dann schlag das hier mal nach: Wilhelm M. schrieb: > class XYZ { > uint8_t buffer[] = {1, 2, 3}; > } Oliver
So scheint es zu gehen Danke noch mal! Ich versuche grade für ein großes Teensy Projekt die Variablen und Funktionen in classen zusammenfassen. Da das noch Neuland ist ist es nicht so einfach. Vielen Dank !! LG Michael
Leider immer noch falsch. BeispielClass::BeispielClass() { // Initialisierung alle drei Werte auf Null byte INPUT_ARRAY[3] { 0,0,0 }; } Da hast Du immer noch eine locale Variable im ctor, die die das Datenelement gleichen Namesn verdeckt.
Michael K. schrieb: > So scheint es zu gehen Danke noch mal! ganz bestimmt nicht.
1 | BeispielClass::BeispielClass() |
2 | {
|
3 | // Initialisierung alle drei Werte auf Null
|
4 | byte INPUT_ARRAY[3] { 0,0,0 }; |
5 | }
|
damit wird nur eine lokale Variabel angelegt die dann gleich wieder gelöscht wird, das willst du bestimmt nicht.
Beim Program Start soll alles auf 0! Ich möchte später einfach auf die Variabel zugreifen! Wann wird gelöscht doch nur beim kompilieren oder ? in dem Alten Program hatte ich einfach vor dem Setup die Variable so deklariert. byte MIDI_INPUT[] = { 0,0,0 }; und das ging ! Ist das so besser ? byte MIDI_INPUT[3] = { 0,0,0 }; ich dachte Variablen die man in einer Classe als public: anlegt sind frei verfügbar in der ino. Ich habe auch schon versucht die ganzen Variable in eine Variablen.h Datei auszulagern und die Funktionen in eine Funktionen.h Datei Der Weg mit den Classen in einer Bibliothek finde ich aber sauberer. Ist beides richtig ?
Michael K. schrieb: > Ist das so besser ? > > byte MIDI_INPUT[3] = { 0,0,0 }; > > ich dachte Variablen die man in einer Classe als public: anlegt > sind frei verfügbar in der ino. ja, wenn sie nicht gerade von einer lokalen Variabel überschrieben werden und das machst du. Wenn du nur willst, das die Variable 0 sind dann mach es so:
1 | #include <Arduino.h> |
2 | #include "ArrayTest.h" |
3 | |
4 | BeispielClass::BeispielClass() |
5 | : INPUT_ARRAY = {0} |
6 | {
|
7 | }
|
Beim nächsten ctor vergisst er wieder die init-list: deswegen in-class initializer verwenden! Wenn der Begriff in-class-initializer unklar ist: selber nachschlagen.
Sorry, der offizielle terminus-technicus ist "default member initializer" Der Name in-class initializer ist eher Jargon ... [1] http://en.cppreference.com/w/cpp/language/data_members
Eigentlich schon, wenn man planvoll vorgeht ... Aber wie gesagt: das Erlernen fällt auf dem PC leichter als auf der MCU. Es gibt auch gute (online) Kurse ...
Peter II schrieb: > Mark B. schrieb: >> Aber sowas im Konstruktor z.B. geht auch nicht: >> >> this->INPUT_ARRAY = { 0,0,0 }; > > was auch klar ist, denn wie soll man die größe der Kasse nur mit Hilfe > der Header-Datei erkennen - und das braucht zwingend der Compiler. Was soll da an der Größe unbestimmt sein? Das Array hat eine Länge von drei mal uint8_t. So ist es in der Header-Datei deklariert.
Wilhelm M. schrieb: > Nein! > Bitte erst mal den Unterscheid zwischen Kopierzuweisung und > Initialisierung lernen! Es hindert niemand eine Programmiersprache daran, den = Operator für die Initialisierung von Arrays zuzulassen. Ich war der Meinung dass C++11 dies kann (nicht C++ generell).
:
Bearbeitet durch User
Der operator=(...) ist keine(!!!) Initialisierung, sondern eine Kopier- oder Verschiebungszuweisung, je nach Signatur.
1 | uint8_i x = 42; // Definition mit Initialisierung |
2 | x = 43; // (Kopier)-Zuweisung |
3 | |
4 | std::array<uint8_t, 10> a = {42}; // Definition mit (Kopier) Initialisieurng |
5 | |
6 | a[3] = 43; // Kopierzuweisung |
Also: das Symbol = der Tastatur meint nicht immer ein Initialisierung ... Bei UDT kann man sich den Unterschied sichtbar machen, indem man bspw. einige der Konstruktoren und den A& operator(const A&) oder A& operator=(A&&) selbst schreibt und mit eine Ausgabe versieht. Aber wie gesagt: das ist alles entry-level C++, was einem klar sein sollte, bevor man mit C++ auf einen uC/MCU geht.
Guten Morgen nur zum Verständniss !! Es geht hier ja um classen und Variablen. in der BeispielClass.h Datei werden die Variablen nur deklariert und definiert ! z.B class BeispielClass { public: BeispielClass(); byte INPUT; private: }; in der BeispielClass.cpp Datei werden die neue angelegten Variablen nur initialisiert ! z.B INPUT = 1000; was ist wenn ich in der BeispielClass.h Datei alles mache ? byte INPUT = 1000; Ist das falsch ? Und dann noch eine Frage zu den Variablen in einer Classe die eigentlich als const vorgesehen sind. In einer Classe kann ich kein z.B. const byte INPUT; deklarierten und definieren. Es geht nur byte INPUT; ohne const ! Wie kann ich in einer Classe const Variablen deklarierten und definieren? Gruß Michael
Was steht denn dazu in deinem C++ Buch, oder in einem der unzähligen Online-Nachschlagwerke? Oliver
Und noch was zu den Dateitypen! In den header Dateien wird immer der Dateitype für Byte so geschrieben uint8 das ist doch das gleiche oder ? byte = 8 Bit 1 Byte Oder sollte ich in der header Datei lieber uint8 schreiben ? Die Arduino.h ist oben eingebunden !
Wilhelm M. schrieb: > Der operator=(...) ist keine(!!!) Initialisierung, sondern eine Kopier- > oder Verschiebungszuweisung, je nach Signatur. Und das ist eine willkürliche Festlegung. Es gibt kein Gesetz, nachdem es zwingend so sein muss und nicht anders sein darf.
Wilhelm M. schrieb: > Steht so im C++ Standard ... weniger willkürlich. Selbstverständlich ist die Festlegung im Standard willkürlich. Verschiedene Programmiersprachen implementieren das gleiche Vorgehen/die gleiche Aufgabe auf verschiedene Art und Weise. Du redest davon wie es ist, ich rede davon wie es sein sollte. C++ und auch C sind an der Stelle alles andere als verständlich. Und wenn etwas wenig verständlich ist, darf man sich ruhig einmal die Frage stellen ob man dies nicht eleganter lösen könnte.
:
Bearbeitet durch User
Aber Du hast schon bemerkt, dass wir hier um C++ reden ... und nicht um dass, was wir uns wünschen, sondern um dass, was wir haben.
Wilhelm M. schrieb: > Steht so im C++ Standard ... weniger willkürlich. In den etwa neueren steht das so nicht... Oliver
Mark B. schrieb: > Wilhelm M. schrieb: >> Der operator=(...) ist keine(!!!) Initialisierung, sondern eine Kopier- >> oder Verschiebungszuweisung, je nach Signatur. > > Und das ist eine willkürliche Festlegung. Es gibt kein Gesetz, nachdem > es zwingend so sein muss und nicht anders sein darf. Es gibt kein Gesetz, aber eine ISO-Norm, in der es so steht. Ob das jetzt willkürlicher ist, als wenn es in einem Gesetz stünde, sei mal dahingestellt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.