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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Michael K. (seq303)


Bewertung
0 lesenswert
nicht 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 Moderator
von Peter II (Gast)


Bewertung
0 lesenswert
nicht 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)


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

Gruß Michael

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


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert

von Peter II (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht lesenswert
Lösung über die initializer-list:

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

von Wilhelm M. (wimalopaan)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht lesenswert
Bei mir kompiliert und läuft es, so wie im Link.

von Peter II (Gast)


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Weil INPUT_ARRAY im ctor eine LOKALE Variable ist!

: Bearbeitet durch User
von Mark B. (markbrandis)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Was soll ich nachschlagen?

von Michael K. (seq303)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
ich schau mal ist alles nicht so einfach!

Danke

von Wilhelm M. (wimalopaan)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


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

Oliver

von Michael K. (seq303)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Steht so im C++ Standard ... weniger willkürlich.

von Mark B. (markbrandis)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Was steht wo nicht?

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.