operatoren überladungsaufgabe



  • c.groupe schrieb:

    ~Bruch(){}
    

    Laut kommenden C++ Standard machst Du durch diese Zeile (benutzerdefinierter Destruktor) aus Bruch eine nicht-trivial kopierbare Klasse. Das ist Deinem Fall aber unnötig und verhindert Optimierungen. Ich würde die Zeile einfach weglassen.

    void operator+ (Bruch other);
    	void operator- (Bruch other);
    	void operator<< (ostream os);
    	void operator>> (istream is);
    

    Dies sollten keine Elementfunktionen sein. Besser:

    // Freie Funktionen in demselben Namensraum wie Bruch:
    inline Bruch operator+(Bruch a, Bruch b)
    {
      return Bruch(
        a.zaehler()*b.nenner()+b.zaehler()*a.nenner(),
        a.nenner()*b.nenner()
      );
    }
    
    inline std::ostream& operator<<(std::ostream& os, Bruch b)
    {
      return os << '(' << b.zaehler() << '/' << b.nenner() << ');
    }
    

    Praktisch wäre noch ein kürzender Kontruktor, der auch dafür sorgt, dass nenner nie negativ ist.



  • l'abra d'or schrieb:

    rüdiger schrieb:

    1. Die operatoren außerhalb der Klasse definieren! + und - sollten keine Member sein. Siehe 3. in got #4.

    Außerhalb der Klasse == freie Funktion, du hast op- und op+ immer noch in der Klasse, zu allem Überfluss sind dir die Rückgabewerte abhanden gekomment :p
    Lies dir das Kapitel im Artikel nochmal durch, und verwechsel auch operator+ und operator += nicht - letzterer macht in der Klasse mehr Sinn 🙂

    ja stimmt schon das der += operator angebrachter wäre, aber das ist eben nicht gefragt gewesen. trotzdem danke. 🙂



  • krümelkacker schrieb:

    Praktisch wäre noch ein kürzender Kontruktor, der auch dafür sorgt, dass nenner nie negativ ist.

    Vielen Danke erstmal, so langsam klappts nun auch immer besser.
    Ja stimmt, zumindest soll man ja, wenn kein nenner übergeben wird ihn mit:
    nenner = 1; initialisieren.



  • so nun klappt schon mal das eingeben und ausgeben, fehlt nur noch,
    die beiden brüche auch zu benutzen..

    /*
     * Bruch.cpp
     *
     *  Created on: 03.02.2010
     *      Author: c.groupe
     */
    #include <iostream>
    using namespace std;
    
    class Bruch
    {
    public:
    	// Konstruktoren
    	Bruch( int zaehler, int nenner = 1 ): itsZaehler(zaehler), itsNenner(nenner) {}
    
    	// Zugriffsfunktionen
    	void setZaehler( int zaehler ) { itsZaehler = zaehler; }
    	int getZaehler() const { return itsZaehler; }
    	void setNenner( unsigned int nenner ) { itsNenner = nenner; }
    	unsigned int getNenner() const { return itsNenner; }
    
    	// Operatoren
    	void operator+ (Bruch other);
    	void operator- (Bruch other);
    	void operator<< (ostream os);
    	void operator>> (istream is);
    
    private:
    	int itsZaehler;
    	unsigned int itsNenner;
    };
    
    // Initialisieren der Operatoren ausserhalb der Klasse
    // Freie Funktionen in demselben Namensraum wie Bruch:
    inline Bruch operator+(Bruch a, Bruch b)
    {
      return Bruch(
        a.getZaehler()*b.getNenner()+b.getZaehler()*a.getNenner(),
        a.getNenner()*b.getNenner()
      );
    }
    
    inline Bruch operator-(Bruch a, Bruch b)
    {
      return Bruch(
        a.getZaehler()*b.getNenner()-b.getZaehler()*a.getNenner(),
        a.getNenner()*b.getNenner()
      );
    }
    
    inline std::ostream& operator<<(std::ostream& os, Bruch b)
    {
      return os << '(' << b.getZaehler() << '/' << b.getNenner() << ')';
    }
    
    /*
    inline std::istream& operator>>(std::istream& os, Bruch b)
    {
      return is >> b.setZaehler() >> b.setNenner();
    }
    */
    
    int main()
    {
    	int z1, n1, z2, n2;
    	cout << "Geben Sie Zähler.1 und Nenner.1 ein: ";
    	cin >> z1; cin >> n1;
    	Bruch a(z1,n1);
    	cout << "Geben Sie Zähler.2 und Nenner.2 ein: ";
    	cin >> z2; cin >> n2;
    	Bruch b(z2,n2);
    
    	cout << "Bruch a: " << a << "\tBruch b: " << b;
    }
    


  • Hab ichs oder hab ichs ? 😃 😃 😃

    /*
     * Bruch.cpp
     *
     *  Created on: 03.02.2010
     *      Author: c.groupe
     */
    #include <iostream>
    using namespace std;
    
    class Bruch
    {
    public:
    	// Konstruktoren
    	Bruch( int zaehler, int nenner = 1 )
    		: itsZaehler(zaehler), itsNenner(nenner) {}
    
    	// Zugriffsfunktionen
    	void setZaehler( int zaehler ) { itsZaehler = zaehler; }
    	int getZaehler() const { return itsZaehler; }
    	void setNenner(  int nenner ) { itsNenner = nenner; }
    	int getNenner() const { return itsNenner; }
    
        // Operatoren
        const Bruch Bruch::plus( Bruch const& rhs ) const; //Implementiert die Addition
        const Bruch Bruch::minus( Bruch const& rhs ) const; //Implementiert die Subtraktion
        std::ostream& Bruch::outputToStream( std::ostream& ) const;
        std::istream& Bruch::imputToStream( std::istream& ) const;
    
    private:
    	int itsZaehler;
    	unsigned int itsNenner;
    };
    
    // Initialisieren der Operatoren ausserhalb der Klasse
    // Freie Funktionen in demselben Namensraum wie Bruch:
    inline Bruch operator+( Bruch &a, Bruch &b )
    {
    	return Bruch(
        a.getZaehler()*b.getNenner()+b.getZaehler()*a.getNenner(),
        a.getNenner()*b.getNenner() );
    
    }
    
    inline Bruch operator-(Bruch &a, Bruch &b)
    {
      return Bruch(
       a.getZaehler()*b.getNenner()-b.getZaehler()*a.getNenner(),
       a.getNenner()*b.getNenner() );
    
    }
    
    inline std::ostream& operator<<(std::ostream& os, Bruch b)
    {
      return os << "( " << b.getZaehler() << " / " << b.getNenner() << " )";
    }
    
    int main()
    {
    	int z1, n1, z2, n2;
    	cout << "Geben Sie Zähler.a und Nenner.a ein: ";
    	cin >> z1; cin >> n1;
    	Bruch a(z1,n1);
    	cout << "Geben Sie Zähler.b und Nenner.b ein: ";
    	cin >> z2; cin >> n2;
    	Bruch b(z2,n2);
    	a= a+b;
    	b= a-b;
    	cout << "(Bruch a + Bruch b) Ergebniss: " << a << endl;
    	cout << "(Bruch a - Bruch b) Ergebniss: " << b << endl;
    }
    


  • c.groupe schrieb:

    class Bruch
    {
    public:
    ...
        // Operatoren
        const Bruch Bruch::plus( Bruch const& rhs ) const; //Implementiert die Addition
        const Bruch Bruch::minus( Bruch const& rhs ) const; //Implementiert die Subtraktion
        std::ostream& Bruch::outputToStream( std::ostream& ) const;
        std::istream& Bruch::imputToStream( std::istream& ) const;
    

    Was soll das denn? Wegschmeißen, diese Deklarationen.



  • Jap, hab ich auch grad gemerkt 🙂

    /*
     * Bruch.cpp
     *
     *  Created on: 03.02.2010
     *      Author: c.groupe
     */
    #include <iostream>
    using namespace std;
    
    class Bruch
    {
    public:
    	// Konstruktoren
    	Bruch( int zaehler, int nenner = 1 )
    		: itsZaehler(zaehler), itsNenner(nenner) {}
    
    	// Zugriffsfunktionen
    	void setZaehler( int zaehler ) { itsZaehler = zaehler; }
    	int getZaehler() const { return itsZaehler; }
    	void setNenner(  int nenner ) { itsNenner = nenner; }
    	int getNenner() const { return itsNenner; }
    
    private:
    	int itsZaehler;
    	unsigned int itsNenner;
    };
    // Initialisieren der Operatoren ausserhalb der Klasse
    // Freie Funktionen in demselben Namensraum wie Bruch:
    inline Bruch operator+( Bruch &a, Bruch &b )
    {
    	return Bruch(
        a.getZaehler()*b.getNenner()+b.getZaehler()*a.getNenner(),
        a.getNenner()*b.getNenner() );
    }
    
    inline Bruch operator-(Bruch &a, Bruch &b)
    {
      return Bruch(
       a.getZaehler()*b.getNenner()-b.getZaehler()*a.getNenner(),
       a.getNenner()*b.getNenner() );
    }
    
    inline std::ostream& operator<<(std::ostream& os, Bruch b)
    {
      return os << "( " << b.getZaehler() << " / " << b.getNenner() << " )";
    }
    
    int main()
    {
    	int z1, n1, z2, n2;
    	cout << "Geben Sie Bruch a ein: Zähler Nenner: ";
    	cin >> z1; cin >> n1;
    	Bruch a(z1,n1);
    	cout << "Geben Sie Bruch b ein: Zähler Nenner: ";
    	cin >> z2; cin >> n2;
    	Bruch b(z2,n2);
    	a= a-b;
    	cout << "(Bruch a - Bruch b) Ergebniss: " << a << endl;
    	return 0;
    }
    

    klappt 😉



  • Und jetzt sind wir noch constkorrekt und vermeiden unnötige Kopien:

    inline Bruch operator+( const Bruch &a, const Bruch &b ) { //
    
    inline Bruch operator-(const Bruch &a, const Bruch &b) { //
    
    inline std::ostream& operator<<(std::ostream& os, const Bruch& b) { //
    


  • so nun müsste dann ja eigenltlich alles fertig sein.
    war ne schoene aufgabe, hab viel gelernt.
    danke an alle 🙂

    edit: nein, eine frage noch

    warum ist es eigentlich egal wenn ich bei den operatoren
    a und b on value oder on referenz übergebe ?

    inline Bruch operator-(Bruch a, Bruch b)
    inline Bruch operator-(Bruch& a, Bruch& b)

    ?



  • c.groupe schrieb:

    warum ist es eigentlich egal wenn ich bei den operatoren
    a und b on value oder on referenz übergebe ?

    inline Bruch operator-(Bruch a, Bruch b)
    inline Bruch operator-(Bruch& a, Bruch& b)

    Ist es nicht.

    Hausaufgabe: Im C++ Buch nachlesen, wie Referenzen funktionieren, wie sie initialisiert werden, was "const" in diesem Kontext für eine Rolle spielt.


Anmelden zum Antworten