Operator von mehrdimensionalem Vector
-
Hallo,
ich hab eine Klasse welche unter anderem ein pixel-Attribut als 2dim-Vector hat. Ich hab bereits Methoden zum Schreiben und Auslesen dieses Vecs geschrieben.
TMycl{ private: vector < vector <int> > pixel; .... public: setPixel(int x, int y, int val); int getPixel(int x, int y);Ich möchte aber nun das Attribut ueber einen []-Operator ansprechen
TMycl cl; cl[0][0] // wert von pixel[0][0]Ich hab bereits ein wenig rumprobiert
cl::operator [](int _x)wusste ich noch dank der Borland-Hilfe, wie ich aber jetzt 2 Argumente uebergebe
cl::operator [][](int _x, int _y)ist mir unbekannt. Wenn ich das probiere erhalte ich einen Compiler-Fehler. Welchen kann ich nicht sagen, hab auf diesem PC die IDE nicht vorhanden.
Ich hoffe aber mein Problem ist verständlich und freue mich über Anregungen.
-
Der Trick ist: du lässt operator[] ein Proxy Objekt liefern, dass selber einen operator[] hat.
-
Hy,
also muss ich praktischen meinen Pixel nicht "direkt" definieren, sondern von einer Klasse und die Klasse hat als Methode wieder den []-operator?
Geht das vllt ein wenig geschmeidiger? ;-).
Wäre klasse wenn noch ein paar Zeilen Code da wären.
-
Durch myPixel[x][y] hast du dann im Endeffekt (myPixel[x])[y].
Müsste klappen.
-
Klingt logisch, werde es heute ausprobieren und geb morgen bescheid.
Danke.
-
Hat soweit geklappt
vector <int>cl::operator [](int _x) { return this->pixel[_x] }Macht das was ich wollte.
Ist es möglich, dass ich den selben Operator auch noch zum setzen von Werten benutzte?
cl[0][0] = 1;Hab damit ein wenig rumgespielt und mir die Frage gestellt ob das überhaupt möglich ist, da ich ja hier wirklich 2 Werte übergeben muss!?
-
dein operator übergibt eine kopie des vectors zurück (was wohl ein bisschen unperformant werden könnte) - gib stattdessen eine referenz auf den vector zurück:
vector<int>& cl::operator [](int x) { return pixel[x]; }
-
Und wenn du das mit der Referenz machst, sollte der Operatore auch einwandfrei zum Setzen von Werten geeignet sein.
-
Ich hab den Code übernommen, hat aber nicht geklappt. Bekomme beim Setzen eine Exception. Habe zuvor aber den Vektor mit resize auf beiden Dimensionen bearbeitet. (Da ich hier keine IDE habe, kann ich die Exception jetzt nicht abschreiben).
Ich würde auch viel lieber, nicht einfach den Wert setzen, sondern ihn an eine Methode weitergeben. Also wenn ich den Wert ausgeben will (geht ja soweit Fehlerfrei) einfach die Ausgabe, beim Setzen, moechte ich SetPixel aufrufen, die u.a. überprüft ob der Wert über der size() des Vektors liegt und ihn dann ggf. noch vergrößert.
Ist sowas möglich?
-
void setPixel(int x, int y, int value){ if (pixel.size() <= x) pixel.resize(x+1); if (pixel[x].size() <= y) pixel[x].resize(y+1); pixel[x][y] = value; }
-
Hy Fellhuhn,
genau dass macht ja meine setpixel ;).
Es geht nur darum, dass wenn ich class[0][0] aufrufe soll er mir den Wert zurückgeben, wenn ich aber class[0][0] = 3 aufrufe soll er ueber die Methode setpixel den Wert speichern.
Daher die Frage wie und ob sich das realisieren lässt.
-
dafür brauchst du ein proxy-objekt. theoretisch sieht das in etwa so aus:
class Graphic { vector<vector<int> > pixel; public: class Proxy { Graphic& parent; int x; public: Proxy (Graphic& parent, int x) : parent(parent), x(x) {} int& operator[] (int y) { parent.set_pixel(x, y); return parent.get_pixel(x, y); } }; Proxy operator[] (int x) //zum modifizieren { return Proxy(*this, x); } vector<int> const& operator[] (int x) const //zum reinen auslesen { return pixel[x]; } void set_pixel (int x, int y); int& get_pixel (int x, int y); }; //...aber google mal danach, um vor- und nachteile von so etwas in erfahrung zu bringen.
/edit: beispiel vervollständigt