Forum: Compiler & IDEs Array in einer Class richtig deklarieren??


von Michael K. (seq303)


Lesenswert?

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
von Peter II (Gast)


Lesenswert?

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.

von Michael K. (seq303)


Lesenswert?

wie würde so was aussehen ? geht das nicht einfacher ?

Gruß Michael

von J. F. (Firma: Père Lachaise) (rect)


Lesenswert?

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
von Tom (Gast)


Lesenswert?


von Peter II (Gast)


Lesenswert?

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?

von J. F. (Firma: Père Lachaise) (rect)


Lesenswert?

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?

von Flauschi (Gast)


Lesenswert?

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.

von Di P. (drpepper) Benutzerseite


Lesenswert?

Lösung über die initializer-list:

http://coliru.stacked-crooked.com/a/fad408956d72c220

von Wilhelm M. (wimalopaan)


Lesenswert?

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};
}

von Peter II (Gast)


Lesenswert?

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.

von Di P. (drpepper) Benutzerseite


Lesenswert?

Bei mir kompiliert und läuft es, so wie im Link.

von Peter II (Gast)


Lesenswert?

Di P. schrieb:
> Bei mir kompiliert und läuft es, so wie im Link.

da ist ja auch kein C Array mehr drin.

von Di P. (drpepper) Benutzerseite


Lesenswert?

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?

von Peter II (Gast)


Lesenswert?

Di P. schrieb:
>> da ist ja auch kein C Array mehr drin.
>
> was denn sonst?

oh sorry, ich dachte da steht ein std::array

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Mark B. (markbrandis)


Angehängte Dateien:

Lesenswert?

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?

von Wilhelm M. (wimalopaan)


Lesenswert?

Weil INPUT_ARRAY im ctor eine LOKALE Variable ist!

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Ä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?

von Peter II (Gast)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

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++ ;-)

von Oliver S. (oliverso)


Lesenswert?

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

von Wilhelm M. (wimalopaan)


Lesenswert?

Was soll ich nachschlagen?

von Michael K. (seq303)


Angehängte Dateien:

Lesenswert?

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

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Michael K. (seq303)


Lesenswert?

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 ?

von Peter II (Gast)


Lesenswert?

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
}

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

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

von Michael K. (seq303)


Lesenswert?

ich schau mal ist alles nicht so einfach!

Danke

von Wilhelm M. (wimalopaan)


Lesenswert?

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 ...

von Mark B. (markbrandis)


Lesenswert?

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.

von Mark B. (markbrandis)


Lesenswert?

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
von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Michael K. (seq303)


Lesenswert?

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

von Oliver S. (oliverso)


Lesenswert?

Was steht denn dazu in deinem C++ Buch, oder in einem der unzähligen 
Online-Nachschlagwerke?

Oliver

von Michael K. (seq303)


Lesenswert?

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 !

von Mark B. (markbrandis)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

Steht so im C++ Standard ... weniger willkürlich.

von Mark B. (markbrandis)


Lesenswert?

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
von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Oliver S. (oliverso)


Lesenswert?

Wilhelm M. schrieb:
> Steht so im C++ Standard ... weniger willkürlich.

In den etwa neueren steht das so nicht...

Oliver

von Wilhelm M. (wimalopaan)


Lesenswert?

Was steht wo nicht?

von Rolf M. (rmagnus)


Lesenswert?

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
Noch kein Account? Hier anmelden.