Übergabewert bei Operatorüberladung?
-
Hallo,
Ich probiere gerade ein bisschen mit Operatorüberladung rum und kapier einfach nicht warum folgendes passiert. Das hier ist meine Test-main:
int main(void) { Vector vec1(4.0,4.0,2.0); vec1 *= 1.5; vec1.getContent(); Vector vec2(4.0,4.0,2.0); vec2 = vec2 * 1.5; vec2.getContent(); return EXIT_SUCCESS; }Das hier passiert in meiner Vektorklasse:
class Vector { public: Vector(float x, float y, float z) : x(x), y(y), z(z) {} virtual ~Vector() {} void getContent() { std::cout << " x: " << x << " y: " << y << " z: " << z << "\n"; } inline const Vector operator *= (float scale) { return Vector ( scale * x, scale * y, scale * z ); } private: float x,y,z; }; inline const Vector operator * (float scale, Vector& rhValue) { return rhValue *= scale; } inline const Vector operator * (Vector& lhValue, float scale) { return lhValue *= scale; }Was ich jetzt nicht versteh ist warum die Ausgabe dazu das hier liefert:
x: 4 y: 4 z: 2 x: 6 y: 6 z: 3Im Prinzip geht das doch alles durch den *= Operator oder? Aber warum kommt das eine bei vec2 an und das andere bei vec1 nicht? Danke schonmal im voraus

alo
-
Anstatt dir jetzt die Lösung vorzuschwafeln, gebe ich dir lieber einen Tipp.
Schau mal ganz genau, was du mit den Rückgabewerten machst und was du für Objekte veränderst in der Funktion.
Ist es this, oder ein neues Objekt? Was wird den da Kopiert?Wenn du das ganz genau anschaust, wirst du merken, wo dein Denkfehler ist.

-
Hmmm...
Die Lösung vorzuschwafeln wäre mir lieber, weil ich irgendwie auf dem Schlauch stehe und jetzt schon etwas länger draufschaue. *g Ich gebe immer ein neues Objekt zurück dachte ich ... ?
-
Versuche das Ganze so zu gestalten:
inline Vector& operator *= (float scale) { x *= scale; y *= scale; z *= scale; return *this; }
-
alo schrieb:
Ich gebe immer ein neues Objekt zurück dachte ich ... ?
Ja. Genau. Und das ist ja das Problem.
Vector vec1(4.0,4.0,2.0); vec1 *= 1.5; vec1.getContent();Warum erstellst du hier ein neues Objekt und veränderst du das?
Der Sinn von *= ist ja, dass du das Objekt veränderst.
Und zurückgeben solltest du eine Referenz auf this. (bei dir noch nicht problematisch, sondern bei Verkettungen dann.)inline const Vector operator *= (float scale) { return Vector ( scale * x, scale * y, scale * z ); }Eher so: (inline ist überflüssig)
const Vector& operator *= (float scale) { this->x *= scal; this->y *= scal; this->z *= scal; return *this; }
-
oh man...
Super viele Dank euch beiden!
Ich versteh aber irgendwie trotzdem nicht, wieso dann der vec2 den richtigen Wert bekommt. Da wird ja genauso ein neues Objekt übergeben? Wäre super, wenn wir ihr mir das noch erklären könntet

-
Die Sache ist, dass deine Version der Funktion die Membervariablen x, y, z unverändert lässt. Es erzeugt nur ein neues Objekt und dieses wird dann zurückgegeben. Damit es einen Effekt gibt, musst du in der Funktion die Membervariablen verändern.
Das was zurückgegeben wird spielt eigentlich keine Rolle, es sei denn du willst den Operator auf folgende Weise anwenden:anderer_vec = vec1 *= 1.5;
dann wird der Rückgabewert des überladenen Operators nach anderer_vec kopiert.
-
Aha, ok... prima... Nochmal Danke! Ich glaub ich habs jetzt
