operator[] für 2D Array überladen
-
Also ich hab mir eine Klasse mit folgendem (kurz) gebaut:
void ***Array; Array = new void**[BreiteX]; for (int x=0; x<BreiteX; x++) Array[x] = new void*[HoeheY];
Jetzt wollte ich gern den []Operator so überladen, das ich da ganz normal über Array[x][y] darauf zugreifen kann.
Ich hab das in einem Buch gelesen aber das ist dort wesentlich einfacher, da nur eine Dimension und nicht dynamisch.
Bin für jeden Tip und auch Erklärungen dafür dankbar.
P.S. Wie überlädt man den Operator[] überhaupt, um ihn so [][] einzusetzen?
Wenn ich das wüste könnte ich das ganze auch normal über ein 1DArray machen und die Position umrechnen, wie es ja normalerweise auh gemacht wird.
-
Bin für jeden Tip und auch Erklärungen dafür dankbar.
Mein Tip. Einfach mal einen Blick in unsere FAQs werfen:
http://www.c-plusplus.net/forum/topic,39489.htmlIm zweiten Beispiel findest du, was du suchst.
-
int* operator[](int Zeile)
{
// Array liegt "zeilenweise" im Speicher
return & pArr[Zeile * Cols];
}Das versteh ich nicht so ganz, kann mir das jemand noch näher bringen. Ansonsten danke erstmal für den Link.
Was ich nicht verstehe:
Man rechnet Zeile* Cols (Cols ist die Anzahal der Spalten und Zeile wir dübergeben)
wenn ich jetz schreibe Array[2][2], welches [] nimmt der da? Irgendwie verstehe ich die Berechnung nicht und nur abschreiben will ich eigentlich nicht.
-
der erste op[] ist natuerlich der der array klasse, und der liefert dir einen pointer der auf das element in pArr (interne repraesentation) zurueck, wo die 2. zeile anfaengt. der zweite op[] ist der ganz normale eingebaute, der nochmal 2 elemente draufaddiert.
-
Auch wenn mich jetzt bestimmt die Hälfte für Begriffsstutzig hält, ich komm da nicht mit.
Noch ne andere Frage, ich möchte ja keine int Speichern sonder Void* Zeiger
also würde ich dann Logischerweise statt int* - void** schreiben, oder?Naja, ich geh erstma mit den Hund raus, vielleicht braucht mein Gehirn auch nur frische Luft.
Irgendwie so:??
void** operator[](int Zeile) { return & pArr[Zeile * Cols] };
-
void*? wo lebst du denn! je nach anwendungsgebiet willst du entweder ein template oder eine gemeinsame basisklasse.
und willst du das absichtlich selber machen, oder weisst du nur nix von vector und co?
-
Vector und Co, kenn ich, wollte ich aber nicht benutzen.
Ich wollte nur ein simples 2D-Array erstellen in dem Zeiger gespeichert werden. Und da ich das mehrmals für verschiedene Sachen brauche, dachte ich, mach ich Zeiger auf void.
In Vector und co steckt son haufen Methoden die ich nie brauche, ich will nur das Array für Zeiger und Zugriff über [][].
----------------------------------------------------------------------------
Jetzt aber nochmal zu meinem verstehens Problem, ich erklärs mal aus meiner sichweise, vielleicht sieht dann jemand meinen Denkfehler.Also ich hab ein 1DArray mit Größe 4*4 erstellt
wenn ich dann meinetwegen auf Array[2][3] zugreife macht er?:int* operator[](int Zeile)
{
return & pArr[Zeile * Cols];
}also bekomme ich einen Zeiger auf 24= 8
und dann beim zweiten Durchgang 34 = 12
8+12 =20 aber mein Array hat nur 16 Stellen.
-
was fuer ein zweiter durchgang? ich habs dir doch schon erklaert. der zweite op[] wird nicht auf das 2darray sondern auf den vom ersten op[] returnten pointer angewendet. also nur +3.
und void pointer solltest du trotzdem nicht verwenden. die alternativen hab ich schon genannt. ich wuerd wahrscheinlich ein template nehmen, weil das array ja keinerlei eigenschaften der verwalteten objekte benutzt.
-
PeterTheMaster schrieb:
was fuer ein zweiter durchgang? ... der zweite op[] wird nicht auf das 2darray sondern auf den vom ersten op[] returnten pointer angewendet. also nur +3.
Sorry, falls es nervt.
Und das ist das was ich daran nicht verstehe? Wieso wird die Überladung des Operators[] nur beim ersten mal genommen und beim zweiten mal dann einfach +3.
Der Operator[] ist doch trotzdem so überladen.Ok, ich werd das dann mit Templates machen.
---------------------------------------------------------------
Ich glaub, jetzt geht mir ein Licht auf.
Also beim ersten mal bezieht sicher der operator[] auf das Array und wird deshalb s wie ich ihn überlade ausgeführt. beim zweiten mal ist das kein Array mehr, sondern nur noch ein Zeiger und da tut er nur den Pointer 3 weiter zurückgeben? So?
-
hast du dir das beispiel in der faq ueberhaupt durchgelesen? dieser operator wird dort fuer diese array2d klasse ueberladen. wenn man also auf ein objekt dieser klasse [] aufruft, wird der ausgefuehrt. wenn man [] auf einen pointer anwendet wird der ganz normale eingebaute genommen. das hab ich genau so schonmal geschrieben. du musst schon bisschen mitdenken.
-
Das hat nicht mit mitdenken zu tun, sondern mit verstehen. Aber jetzt hab ichs ja verstanden.
-
ich glaube ich fasse es nochmal kurz zusammen :
der aufruf : Array[2][2]
beinhaltet 2x den aufruf des operators [].
der operator [] des objekts Array ist überladen und gibt ein array (also nicht Array) zurück, zb. vom typ void **.
cols gibt bei den genannten codebeispielen nun an wieviele spalten Array hat. ist es als ein array der dimension 5x6, so ist cols = 6.
wie gesagt gibt der operator [] von Array ein array mit eienr dimension weniger zurück. auf dieses array wird nun der zweite operator [] angewendet.
das ist also in diesem fall eine hintereinanderausführung zwei verschiedener operatoren [] !
man könnte es auch so schreiben : (Array[2])[2]