Typumwandlung durch Operatoren Codeverständnis
-
Hallo,
ich folge grade einem Anfängerkurs in C++ und habe leider ein Verständnisproblem an einer kaum dokumentierten Stelle. Hier zunächst einmal der Code:
class Bruch { public : explicit Bruch ( int x = 0 , int y = 1){ p_x = x ; p_y = y ; } operator double () const { return ( double ) ( p_x / p_y ); } private : int p_x , p_y ; // Zähler und Nenner int main () { Bruch x (5 , 2); double y ; y = x * 15; // x - > double y = 10 * x ; // hier auch möglich x - > double return 0; }
Soweit ich das verstanden habe erhält der Operator immer das linke Objekt automatisch als Zeiger, das rechte optional per expliziter Übergabe. Diese Theorie passt allerdings nicht zu dem Beispiel. #
Als Erlärung wurde angegeben das x mittels des Operators von Bruch nach double umgewandelt wird.
Kann mir jemand erklären wie der Code funktioniert? Ich habe mich jetzt eine halbe Stunde damit beschäftigt, kommt aber nicht weiter.
-
Da es hier keinen definierten "operator *(Bruch, double)" gibt, aber den "operator double () const", führt der Compiler eine Typumwandlung (cast) hier durch, so als ob folgendes im Code stehen würde:
y = (double)x * 15; // x - > double y = 10 * (double)x; // hier auch möglich x - > double
Edit: Und dann werden jeweils 2 double-Multiplikationen durchgeführt.
-
Mit den offensichtlichen Syntaxkorrekturen:
class Bruch { public : explicit Bruch ( int x = 0 , int y = 1){ p_x = x ; p_y = y ; } operator double () const { return ( double ) ( p_x / p_y ); // der Cast kommt zu spät, die Division wurde bereits als Ganzzahldivision durchgeführt // nur das Ergebnis wird nachträglich nach double konvertiert (das würde aber auch implizit passieren) } private : int p_x , p_y ; // Zähler und Nenner }; int main () { Bruch x (5 , 2); double y ; y = x * 15; // x ist int, 15 ist ein int => Multiplikation erfolgt als int, umgewandelt wird erst bei der Zuweisung des Multiplikationsergebnisses y = 10 * x ; // dito return 0; }
-
Wie kommst du darauf: "x ist int"?
OK, daß die Division im operator double() falsch ist, hatte ich vorher nicht gesehen, trotzdem wird ja ein double-Wert zurückgegeben, so daß wegen der Promotion bei der Multiplikation implizit der andere Operand (d.h. der int-Wert) in ein double umgewandelt wird.Die Namensgebung im Code ist natürlich suboptimal, da x doppelt für 2 verschiedene Typen benutzt wird (int und Bruch).
-
Th69 schrieb:
Wie kommst du darauf: "x ist int"?
Mein Fehler. p_x != x
Leicht zu verwechselnde Namen sind aber dem TE anzulassten.Also richtig:
class Bruch { public : explicit Bruch ( int x = 0 , int y = 1){ p_x = x ; p_y = y ; } operator double () const { return ( double ) ( p_x / p_y ); // der Cast kommt zu spät, die Division wurde bereits als Ganzzahldivision durchgeführt // nur das Ergebnis wird nachträglich nach double konvertiert (das würde aber auch implizit passieren) } private : int p_x , p_y ; // Zähler und Nenner }; int main () { Bruch x (5 , 2); double y ; y = x * 15; // x ist ein Bruch, es existiert kein überladener op*, der ein Bruch als linken Operanden nimmt. // Der eingebaute Operator* ist anwendbar, da eine eindeutige Konvertierung in einen arithmetischen Typ (double) existiert // die gewöhnlichen arithmetischen Konvertierungen sorgen dann dafür, dass auch der rechte Operand zu double konvertiert wird y = 10 * x ; // ditto return 0; }
-