C++ Anfänger Operatoren-Überladen



  • Hallo Leute!

    Ich bin noch ein C++ Anfänger und beschäftige mich gerade mit dem Überladen von Operatoren. In meinem Programm handelt es sich um Brüche und für diese wollte ich einige Operatoren überladen. Nun bekomme ich jedoch folgende Fehlermeldung, mit der ich nichts anzufangen weiss:

    Fraction.cpp:28:56: Fehler: Die �bergabe von �const Fraction� als �this�-Argument von �int Fraction::getNumerator()� streicht Qualifizierer [-fpermissive]

    Fraction.cpp:29:60: Fehler: Die �bergabe von �const Fraction� als �this�-Argument von �int Fraction::getDenominator()� streicht Qualifizierer [-fpermissive]

    Hier ist meine Header-Datei

    /* 
     * File:   Fraction.h
     * Author: Xarsis
     *
     * Created on 24. Juni 2012, 15:48
     */
    
    #ifndef FRACTION_H
    #define	FRACTION_H
    
    #include <iostream>
    
    using namespace std;
    
    class Fraction {
    public:
        Fraction();
        Fraction(int numerator, int denominator);
        int getNumerator();
        int getDenominator();
        Fraction operator*(const Fraction& rhs);
        void operator<<(const Fraction& fraction);
    private:
        int numerator;
        int denominator;
    };
    
    #endif	/* FRACTION_H */
    

    und hier meine .cpp

    /* 
     * File:   Fraction.cpp
     * Author: Xarsis
     *
     * Created on 24. Juni 2012, 15:48
     */
    
    #include "Fraction.h"
    
    Fraction::Fraction() {
    
    }
    
    Fraction::Fraction(int numerator, int denominator) {
        this->numerator = numerator;
        this->denominator = denominator;
    }
    
    int Fraction::getNumerator() {
        return this->numerator;
    }
    
    int Fraction::getDenominator() {
        return this->denominator;
    }
    
    Fraction Fraction::operator*( const Fraction& rhs) {
        Fraction result(this->numerator * rhs.getNumerator(),
                        this->denominator * rhs.getDenominator());
        return result;
    }
    
    void Fraction::operator <<(const Fraction& fraction) {
        cout << fraction.getNumerator() << " / " << fraction.getDenominator();
    }
    

    Vielen Dank schonmal für die Hilfe!


  • Mod

    Du warst nicht konsequent mit der const-correctness. const ist ansteckend. Deine Getter müssen sich noch anstecken, wenn du sie in anderen const-Memberfunktionen benutzen möchtest.

    P.S.: Du weißt, dass du das this-> nicht brauchst? Bist du auch sicher, dass der leere Konstruktor tut, was du möchtest? Derzeit ermöglicht er das uninitialisierte erstellen von Objekten deiner Klasse, obwohl deine Klasse anscheindend doch initialisiert erstellt werden möchte.



  • Ich glaub du hast da ein paar const vergessen.

    int getNumerator() const {return numerator;}
    int getDenominator() const {return denominator;}
    

    ansonsten:
    schau dir mal die Initialisierungsliste an.

    PS: using namespace std; gehört nicht in den header.

    gruß
    syntax



  • Hey danke für eure Antworten!
    Habe das mit dem *operator jetzt hinbekommen mit dem const. Für den <<operator muss ich nochmal schauen, da hatte ich glaub schon einen total falschen Ansatz. Laut Internet wird das mit ostream gemacht. Aber nun ja da werd ich mich nochmal dran setzen.

    @SeppJ
    Ja der leere Konstruktor war in diesem Fall so gewollt und das mit dem this-> weiss ich zwar das ich es auch weg lassen könnte aber mir wurde geraten das so zu machen, damit ich auch gleich sehe das ich auf Sachen zugreiff in dem Objekt indem ich mich befinde. Aber mir fällt grad auf würde das denn in meinem überladenen Konstruktor funktionieren wenn man da schreibt: numerator = numerator ? Woher weiss denn dann der Compiler was gemeint ist? Auf jeden nochmal danke für die Hilfe!

    @Syntax
    Auch dir ein Dankeschön!! Wieso gehört der namespace std nicht in den Header? Hätte ich eine Methode die ich sag mal string oder ostream zurückgeben würde und ich hätte alles included dann brauch ich doch den namespace std sonst würde er meinen string oda ostream nicht erkennen oder sehe ich da was falsch?

    MfG Xarsis



  • Xarsis schrieb:

    Aber mir fällt grad auf würde das denn in meinem überladenen Konstruktor funktionieren wenn man da schreibt: numerator = numerator ? Woher weiss denn dann der Compiler was gemeint ist?

    Da hast du recht, darum macht man so was:

    private:
        int a;        //auch schon gesehen: _a, _b
        int b;
    public:
        Classenname(int aa, int bb) : a(aa), b(bb) {}
    

    Ich mache eigentlich nit this->.

    Xarsis schrieb:

    Für den <<operator muss ich nochmal schauen, da hatte ich glaub schon einen total falschen Ansatz. Laut Internet wird das mit ostream gemacht.

    Ja der ist doch schon überladen:

    std::ostream& operator <<(std::ostream& rhs, T& lhs);  //T steht fuer deinen Datentyp
    

    Xarsis schrieb:

    Wieso gehört der namespace std nicht in den Header?

    Weil es zu Problemen führen kann. Es gibt alternativen:

    using std::cout;
    using std::cin;
    cout<<...;
    cin>>...;
    

    oder:

    std::cout<<...;
    std::cin>>...;
    

    gruß
    syntax



  • Hab das mit dem <<operator noch nicht ganz hinbekommen.
    Man muss den <<operator doch als globale Funktion machen, weil meine links Seite vom Operator ja kein Mitglied meiner Klasse ist. Also hab ich das jetzt so geschrieben, was jedoch auch nicht funktioniert 😢

    Der Fehler ist:

    Fraction.cpp:33:63: Fehler: �std::ostream& Fraction::operator<<(std::ostream&, const Fraction&)� muss genau ein Argument nehmen

    Header

    /* 
     * File:   Fraction.h
     * Author: Xarsis
     *
     * Created on 24. Juni 2012, 15:48
     */
    
    #ifndef FRACTION_H
    #define	FRACTION_H
    
    #include <iostream>
    #include <ostream>
    
    class Fraction {
    public:
        Fraction();
        Fraction(int numerator, int denominator);
        int getNumerator() const;
        int getDenominator() const;
        Fraction operator*(const Fraction& rhs);
    private:
        int numerator;
        int denominator;
    };
    
    std::ostream& operator<<(std::ostream &os, const Fraction &rhs);
    
    #endif	/* FRACTION_H */
    

    CPP

    /* 
     * File:   Fraction.cpp
     * Author: Xarsis
     *
     * Created on 24. Juni 2012, 15:48
     */
    
    #include "Fraction.h"
    
    using namespace std;
    
    Fraction::Fraction() {
    
    }
    
    Fraction::Fraction(int numerator, int denominator) {
        this->numerator = numerator;
        this->denominator = denominator;
    }
    
    int Fraction::getNumerator() const {
        return this->numerator;
    }
    
    int Fraction::getDenominator() const {
        return this->denominator;
    }
    
    Fraction Fraction::operator*(const Fraction& rhs) {
        Fraction result(this->numerator * rhs.getNumerator(),
                this->denominator * rhs.getDenominator());
        return result;
    }
    
    ostream& Fraction::operator<<(ostream &os, const Fraction& rhs) {
        return os << rhs.getNumerator() << " / " << rhs.getDenominator();
    }
    


  • Schau mal in Zeile 26, da steht die operator-funktion ausserhalb deiner Klasse, aber schreibst in Zeile 35 Fraction::operator<<//...

    Du musst diese Funktion als friend deklarieren, wenn du sie in die Klasse packst.

    friend std::ostream& operator<<(std::ostream& os, Fraction& rhs);
    
    std::ostream& operator<<(std::ostream& os, Fraction% rhs){
    
    //Das hier stimmt bei dir
    }
    

    Ansonste hier ein guter tut.
    http://www.c-plusplus.net/forum/232010

    gruß
    syntax



  • Vielen Dank nochmal Syntax! Es funktioniert jetzt alles! Ja ist auch irgendwie logisch das das Fraction:: in der CPP dann weg muss, wenn es kein Mitglied der klasse mehr ist, aber da wär ich in 100 Jahren nicht drauf gekommen! 😃
    Der Tut-Thread ist ja auch sehr genial danke dafür !

    MfG Xarsis


Anmelden zum Antworten