Array in Klasse zuweisen
-
Mh warum geht das nicht? Ist es verboten ein Array in einer Klasse zuzuweisen?
include <iostream> using namespace std; class Vector { public: Vector(); ~Vector(); void push_here(int Wert); void push_front(int Wert); void push_back(int Wert); int push_is(); int position(int Wert); private: const int ARRAY_SIZE; int TopIndex; int data[ARRAY_SIZE]; // <-- Passt ihm nicht! }; Vector::Vector() :ARRAY_SIZE(10),TopIndex(0) { } Vector::~Vector() { } void Vector::push_here(int Wert) { data[TopIndex]=Wert; } void Vector::push_front(int Wert) { TopIndex=TopIndex+1; data[TopIndex]=Wert; } void Vector::push_back(int Wert) { TopIndex=TopIndex-1; data[TopIndex]=Wert; } int Vector::push_is() { return TopIndex; } int Vector::position(int Wert) { return data[Wert]; } int main() { return 0; }Wenn ich dem Array nicht doe konstante zuweise sondern nur eine Zahl dann gehts. Wie kann ich mein Problem lösen sodass es funktioniert?
Dankeschön schon mal im Voraus.
-
Die Arraygröße muss nicht nur konstant, sondern auch zur Compiletime sichtbar sein. D.h. der Compiler muss in Zeile 18 bereits wissen, welchen Wert ARRAY_SIZE haben wird. Das kannst Du in diesem Fall mit static const lösen, denn da ist (laut Standard) eine Zuweisung bereits bei der Klassendeklaration möglich.
static const int ARRAY_SIZE = 10; int data[ARRAY_SIZE];Bei einigen (älteren) Compilern musst Du nen Enum-Hack machen:
enum { ARRAY_SIZE = 10 }; int data[ARRAY_SIZE];
-
Dein Problem ist, daß die Größe eines Arrays bereits zur Compilerzeit festestehen muß. Das Element ARRAY_SIZE ist aber eine Laufzeit-Konstante (daß es im Ctor einen festen Wert zugewiesen bekommt, bemerkt der Compiler nicht), also als Größenangabe ungeeignet. Zur Lösung dieses Problems könntest du das Element statisch deklarieren:
class Vector { ... private: static const int ARRAY_SIZE = 10; int data[ARRAY_SIZE]; }; const int Vector::ARRAY_SIZE;//notwendig für den Linker //oder als Alternative: class Vector { ... private: enum{ARRAY_SIZE = 10}; int data[ARRAY_SIZE]; };
-
Aber ich versteh das noch nicht ganz. Das ARRAY_SIZE steht doch schon während der Laufzeit fest, da ichs doch in der Initialisierungsliste angebe:
Vector::Vector() :ARRAY_SIZE(10),TopIndex(0)und somit steht doch dann auch data fest?
2. wenn ich so drüber nachdenke dann müsste es doch eigentlich auch gehen wenn "data" auf dem Heap ist oder?
Also:int data=new int[ARRAY_SIZE];Soviel wie ich weiß ist es doch so, das man wenn etwas noch nicht zur Compilierzeit festgelegt ist, dann tut man das einfach auf den Heap. Oder ist da static besser? Wo soll den da der Unterschied sein. Mh und meiner Meinung steht es ja während der Laufzeit schon fest. Kanns mir nochmal jemand erklären?
Dankeschön schon mal im Voraus.
-
Stromberg schrieb:
Aber ich versteh das noch nicht ganz. Das ARRAY_SIZE steht doch schon während der Laufzeit fest, da ichs doch in der Initialisierungsliste angebe:
Vector::Vector() :ARRAY_SIZE(10),TopIndex(0)und somit steht doch dann auch data fest?
Nein, tut es nicht (jedenfalls nicht wirklich). Für den Compiler ist ARRAY_SIZE ein Element, das erst durch den Ctor-Aufruf mit einem Wert gefüllt wird (und bei der Klassendefinition sieht er noch nicht, daß dieser Wert immer konstant ist)
2. wenn ich so drüber nachdenke dann müsste es doch eigentlich auch gehen wenn "data" auf dem Heap ist oder?
Also:int data=new int[ARRAY_SIZE];Im Prinzip ja, aber an den Details solltest du da noch etwas feilen:
class Vector { public: ... Vector():ARRAY_SIZE(10),data(new int[ARRAY_SIZE]) {} ~Vector() {delete[]data;} //Anmerkung: Und du benötigst Copy-Ctor und op=, um Speicherfehler zu vermeiden private: const int ARRAY_SIZE; int* data; };Soviel wie ich weiß ist es doch so, das man wenn etwas noch nicht zur Compilierzeit festgelegt ist, dann tut man das einfach auf den Heap. Oder ist da static besser? Wo soll den da der Unterschied sein. Mh und meiner Meinung steht es ja während der Laufzeit schon fest. Kanns mir nochmal jemand erklären?
Dankeschön schon mal im Voraus.In deinem Fall ist wohl eine statische Konstante die bessere Wahl. Der Unterschied zu deiner Original-Variante ist, daß diese einmal für die gesamte Klasse existiert - und im Gegensatz zu einem konstanten Member IST sie eine Compilezeit-Konstante (sprich: du darfst sie als Array-Größe verwenden).
PS: Wenn es dir nicht um den reinen Lerneffekt geht, nimm lieber std::vector<>.