[Anfänger] Arrays in Klassen
-
Hallo
ich versuche gerade eine Klasse zu bauen.
In dieser Klasse gibt es einige (konstante) Arrays z.B.:float t05N2[] = {4, 8, 12.5, 18.5, 27, 38.3, 54.3, 77, 109, 146, 187, 239, 305, 390, 498, 635}; float aN2[] = {1.2599, 1, 0.8618, 0.7562, 0.662, 0.5043, 0.441, 0.4, 0.375, 0.35, 0.3295, 0.3065, 0.2835, 0.261, 0.248, 0.2327}; float bN2[] = {0.505, 0.6514, 0.7222, 0.7825, 0.8126, 0.8434, 0.8693, 0.891, 0.9092, 0.9222, 0.9319, 0.9403, 0.9477, 0.9544, 0.9602, 0.9653};Wenn ich die Grundlagen richtig verstanden habe gehören Variablendeklarationen in die header-Datei.
Wenn ich aber diese Deklaration in die header-Datei packe bekomme ich folgenden Fehler:
zlh16.h|20|error: a brace-enclosed initializer is not allowed here before '{' token| zlh16.h|20|error: ISO C++ forbids initialization of member `t05N2'| zlh16.h|20|error: making `t05N2' static| zlh16.h|20|error: invalid in-class initialization of static data member of non-integral type `float[0u]'|OK, Tante google sagt mir das es halt verboten ist, nicht int Typen zu verwenden, und das man das so nicht macht. Eine Lösung gefunden habe ich aber nicht.
Ich hab dann einfach die Variablen in den Konstruktor gepackt. Das geht.
Aber wie schon oben geschrieben, dachte ich das sowas eigendlich in den Header muß.Wo denke ich falsch?
danke
Christian
-
Du kannst die Array-Initialisierungsliste bei Arrays, die Member einer Klasse sind, nicht verwenden. Du müsstest die Werte also nachträglich zuweisen.
Im neuen Standard sollte das aber möglich sein.
-
Hallo
und wie würde das aussehen?
Was muß ich jetzt in den Header machen und was in den Code? So wie ich es jetzt mache funktioniert es, mit der Deklaration mit Werten in Konstruktor, aber ich will mir gleich beim Erlernen den richtigen Stil angewöhnen. Später abgewöhnen ist so unendlich schwer...gruss
Christian
-
Normalerweise würde man hier einen Container, ala std::vector, oder boost::array nehmen.
Ansonsten kommst du nicht drum herum die Grösse im Header anzugeben und dann einfach im ctor mit einer Schleife zu füllen.
-
So wie du es jetzt machst, ist es aber nur lokal. Die Arrays existieren nach dem Konstruktor nicht mehr.
Der richtige Stil ist, gar keine Arrays zu benutzen.

Das mag zwar blöd klingen, ist aber wahr. Viel besser zu bedienen sind die STL-Container, bei denen man z.B. auch einfach Elemente anhängen kann. Zudem kann man dank Assertions die Fehlerquellen einschränken und das Debugging erleichtern. Bei den Artikeln in diesem Forum gibt es einige Beiträge dazu.
Allerdings kommt es auch relativ selten vor, dass man die Werte "hardcoded" als Literale im Code stehen hat. Liest du die nicht von einer Datei ein? Ansonsten könntest du vielleicht mal Boost.Assign (
list_of()) anschauen, da hat man eine Art Initialisierungslisten für Container.
-
deklariere in der *.h und definiere in der *.cpp
in der *.cpp kannste auch gleich initialisieren.
klappt das?
wenn ja, dann ist es auch die nächsten zehn jahre guter stil. denn es ist recht aufgeräumt und optimal schnell und selbst wenn der neue standard das im header erlaubt, brauchts noch 10 jahre, bis die daten aus dem header bei mehrfacher inklusion bei den meisten compilern nur einmal in der ausführbaren datei landen.
-
Das würde dann auf sowas hinauslaufen:
// ===== Header ===== class Class { static int Array[]; }; // ===== Implementierungsdatei ===== int Class::Array[3] = {1, 2, 4};Aber dazu hätte ich noch eine Frage: Wieso muss man im Header die Dimension nicht angeben? Zum Typ des Arrays gehört die doch?
-
Wiel die ein statisches Array keinen Einfluss auf den Speicherverbrauch der Klasse hat. Sie muss daher auch nicht wissen, wie gross das Array schlussendlich ist.
-
Nexus schrieb:
Aber dazu hätte ich noch eine Frage: Wieso muss man im Header die Dimension nicht angeben? Zum Typ des Arrays gehört die doch?
ich wäre nie auf die idee gekommen, die Dimension hier nicht anzugeben.
für nen compiler ist das hier genauso wie eine array-übergabe bei einem funktionsaufruf. die klasse braucht nur die adresse des ersten elements zu kennen. damit klappt alles.
die größe wäre nur nötig, um indexüberschreitungen zu erkennen, und das macht c++ nicht von allein. so gesehen ist es logisch, daß die größe den compiler nicht juckt. wie bei funktionen auch.
ich halte es gleichermaßen für möglichz, daß der standard es erlaubt wie daß er es nicht erlaubt und der compilerbauer einfach logisch fortgesetzt hat. keine ahnung.
-
Die Frage stellte ich mir, als ich mir eine Situation überlegte, in der die Grösse des Arrays relevant wäre. Das wäre beispielsweise
sizeofoder folgendes Funktionstemplate:template <size_t S> void Function(int (&Array)[S]) { // ... }Ich dachte, dies würde kompilieren, wenn die Dimension nicht angegeben wäre, und fragte mich deshalb, weil diese ja erst zur Linkzeit bekannt wäre. Ich habe mich hier jedoch geirrt, ohne Grössenangabe gibt es einen Compilerfehler.
-
Nexus schrieb:
So wie du es jetzt machst, ist es aber nur lokal. Die Arrays existieren nach dem Konstruktor nicht mehr.
Nach dem Konstruktor nicht mehr oder nach beendigung des Objekts? Daten die der Konstruktor erstellt bestehen doch über die gesammte Objektlebensdauer, oder?
Nexus schrieb:
Allerdings kommt es auch relativ selten vor, dass man die Werte "hardcoded" als Literale im Code stehen hat. Liest du die nicht von einer Datei ein?
Warum sollte ich? Das sind Werte die feststehen... So wie die Halbwertzeit von Radioaktiven Stoffen. Das ist sozusagen von der Natur "hardcoded"
-
nordlichtHH schrieb:
Nach dem Konstruktor nicht mehr oder nach beendigung des Objekts? Daten die der Konstruktor erstellt bestehen doch über die gesammte Objektlebensdauer, oder?
Nicht, wenn ihre Deklaration im Konstruktor selber erfolgt. Das gilt nur für Member der Klasse.
nordlichtHH schrieb:
Warum sollte ich? Das sind Werte die feststehen... So wie die Halbwertzeit von Radioaktiven Stoffen. Das ist sozusagen von der Natur "hardcoded"
Gut, wenn es wirklich solche Konstanten sind, kannst du es schon so lassen. Aber da die Werte eigentlich nicht für jede Instanz kopiert werden müssen, würde ich sie auch global oder statisch (siehe mein vorheriger Beitrag) deklarieren.