C++ rechnen mit rationalen Zahlen



  • Hallo,
    bin auf ein neues Problem gestossen.
    Und zwar soll ich die den Additionsoperator und natürlich die anderen arithmetischen Operatoren (von denen hab ich den Code nicht gepostet) überladen.
    Kann mir jemand von euch anhand des Additionsoperators zeigen, wie das gehen könnte und wie ich das entsprechend einbaue.

    Habe schon folgenden Ansatz:

    rational operator+(rational a, rational b)
    {
             rational t;
             t.zaehler = a.zaehler*b.nenner + b.zaehler*a.nenner;
             t.nenner  = a.nenner*b.nenner;
             t.kuerzen();
             return t;
    }
    
    rational operator+(rational a, rational b)
    {
             return b+a;
    }
    

    Jedoch komm ich da nicht weiter.



  • Was soll der zweite operator bezwecken und was soll "ich komme nicht weiter" heißen? Ist es so schwer eine Frage vernünftig zu stellen?


  • Mod

    Was heißt nicht weiterkommen? So wie ich das sehe bist du schon fertig:

    rational operator+(rational a, rational b)
    {
             rational t;
             t.zaehler = a.zaehler*b.nenner + b.zaehler*a.nenner;
             t.nenner  = a.nenner*b.nenner;
             t.kuerzen();
             return t;
    }
    

    (Wobei man noch erwähnen sollte, dass man den + Operator meistens vom += Operator ableitet, aber das ist eine andere Geschichte)



  • Wie genau bekomme ich das denn nun angewendet? Mein Zaehler und mein Nenner sind ja privat. Und wenn das gelöst is reicht es dann, wenn ich einfach wieder mein Testprogramm benutze?

    ratio.h: In function `rational operator+(rational, rational)':

    ratio.h:30: error: long int rational::zaehler' is private ratio.cpp:92: error: within this context ratio.h:30: error:long int rational::zaehler' is private
    ratio.cpp:92: error: within this context
    ratio.h:30: error: long int rational::nenner' is private ratio.cpp:92: error: within this context ratio.h:30: error:long int rational::zaehler' is private
    ratio.cpp:92: error: within this context
    ratio.h:30: error: long int rational::nenner' is private ratio.cpp:92: error: within this context ratio.h:30: error:long int rational::nenner' is private
    ratio.cpp:93: error: within this context
    ratio.h:30: error: long int rational::nenner' is private ratio.cpp:93: error: within this context ratio.h:30: error:long int rational::nenner' is private
    ratio.cpp:93: error: within this context


  • Mod

    Mach den Operator zum friend!



  • Achso... ich dachte ich bräuchte das nur, wenn ich keinen Typumwandlungskonstruktor habe.
    Müsste dann so aussehen:

    friend rational operator+(long, rational);
    friend rational operator+(rational, long);
    

    ,oder?

    Das setz ich dann direkt über die rational operator?


  • Mod

    expert schrieb:

    Achso... ich dachte ich bräuchte das nur, wenn ich keinen Typumwandlungskonstruktor habe.
    Müsste dann so aussehen:

    friend rational operator+(long, rational);
    friend rational operator+(rational, long);
    

    ,oder?

    Der Operator in deinem Beispiel hat aber die Singatur

    rational operator+(rational, rational);
    

    Das setz ich dann direkt über die rational operator?

    Nein, friend Deklarationen gehören in die Klasse.



  • Vielen Dank für deine Hilfe Sepp!
    Steh aber irgendwie auf dem Schlauch. Ich brauch doch das noch hier:

    rational operator+(rational a, rational b)
    {
             return b+a;
    }
    

    ,oder?

    Und wie kann ich das schließlich angezeigt bekommen? Hab das sonst bei der Addition, z.B. mit erg.add(a,b);
    gemacht.



  • Nachtrag:
    Und wenn ich das einbaue was ich eben gepostet habe bekomme ich vom Compiler:

    ratio.cpp: In function rational operator+(rational, rational)': ratio.cpp:100: error: redefinition ofrational operator+(rational, rational)'
    ratio.cpp:91: error: `rational operator+(rational, rational)' previously defined here

    Wie umgehe ich diese Redefinition?



  • expert schrieb:

    Wie umgehe ich diese Redefinition?

    Indem du die Funktion (hier deinen operator+ ) nur ein einziges Mal definierst. Allerdings gibt es bezüglich Operatorüberladung einige Dinge, die du besser machen könntest (z.B. operator+= in Klasse und operator+ mit dessen Hilfe implementieren, Const-Referenz-Parameter), siehe dazu hier.

    Übrigens:

    rational operator+(rational a, rational b)
    {
             return b+a;
    }
    

    wird zu einer Endlosrekursion und somit zu einem Stackoverflow führen.



  • Sry Leute wenn ich euch nerve, aber ich komme echt nicht weiter.
    Hab

    friend rational operator+(rational, rational);
    

    in der Header Datei.
    Hab mir den Link von Nexus auch angesehen, aber ich werd nich richtig raus schlau...
    Muss dazu sagen, dass ich in C++ noch wenig bis keine Erfahrung habe. Könnte mir vielleicht einer das Beispiel für die Addition geben?
    Kann man das denn nicht zusammenfügen? Und dann a und b über cout ausgeben?

    rational operator+(rational a, rational b)
    {
             rational t;
             t.zaehler = a.zaehler*b.nenner + b.zaehler*a.nenner;
             t.nenner  = a.nenner*b.nenner;
             t.kuerzen();
             return t;
    }
    
    rational operator+(rational a, rational b)
    {
             return b+a;
    }
    

  • Mod

    Was soll denn immer diese zweite Definition?

    rational operator+(rational a, rational b)
    {
             return b+a;
    }
    

    Du hast doch einen schönen Operator + direkt darüber, was soll dieser noch? (abgesehen davon, dass dieser, wie schon oben, erwähnt eine Endlosrekursion ist)



  • Wenn ich diese Zweite Definition nicht habe, habe ich doch fast das gleiche als wenn ich die normale add.Funktion benutze.



  • expert schrieb:

    Wenn ich diese Zweite Definition nicht habe, habe ich doch fast das gleiche als wenn ich die normale add.Funktion benutze.

    Was ist denn das für eine Logik?

    Lies doch bitte den Artikel zur Operatorüberladung. Da werden solche Dinge allesamt erklärt! Und wenn du dann immer noch etwas nicht verstehst, nachdem du es gelesen und darüber nachgedacht hast, kannst du hier konkrete Fragen stellen.

    Und Operatorüberladung ist ein Thema, das man angehen sollte, nachdem man von Klassen schon einen Überblick hat. Zu den Grundlagen gehören auch friend und die One Definition Rule. Vielleicht ist es besser, du verinnerlichst dir zuerst diese Dinge...


Anmelden zum Antworten