+ operator überladen



  • passt dann jetzt der überleadene operator+ ?
    die überprüfung ob die beiden "bez" gleich sind, macht man am besten mit strcpy?



  • Betrag::Betrag(double d) : wert(d) { } // <----
    

    Zumindest wird Variante 1 ohne Fehler kompiliert 😃



  • finix schrieb:

    Betrag::Betrag(double d) : wert(d) { } // <----
    

    Zumindest wird Variante 1 ohne Fehler kompiliert 😃

    Ach du Scheiße, nee 🤡 🤡

    Ab jetzt wird erst alles durch en Compiler gejagt und getestet 🕶 😉



  • 3 seiten und nicht einmal die richtige op+ implementierung 😞

    T operator+(T a, T const& b)
    {
      a+=b;
      return a;
    }
    

    so baue ich idr meinen op+ 🙂

    schoen kurz, nicht?



  • Shade: Ich wusste, ich hab was vergessen (nämlich den op+ anzufassen).


  • Mod

    class Betrag {
    public:
        double wert;
        std::string bez;
    
    public:
    
        Betrag();
        Betrag(double y) : wert( y ) { }
    /*    Betrag (const Betrag& abc) {
    		wert = abc.wert;
    		bez =abc.bez;
    	}*/
    
    };		
    const Betrag operator+(const Betrag& b1, const Betrag& b2) {
        return Betrag( b1.wert + b2.wert );
    }
    

    + sollte eine const Betrag zurückliefern, ansonsten wäre so etwas wie

    ( a + b ) = c;
    

    möglich, was sinnlos und unintuitiv wäre. Das wiederum impliziert, dass + argumente als reference-to-const nehmen muss, sonst könnte man ja nicht

    d = a + b + c;
    

    schreiben. Einen Copy-C'tor wiederum sollte man nicht schreiben, wenn der default-copy-c'tor dasselbe tut. erstens ist es überflüssig, zweitens verhindert es häufig sinnvolle optimierungen durch den compiler.
    z.b. wird bei

    c = a + b;
    

    wenn kein = operator und copy-c'tor definiert sind, wird jeder compiler, der etwas taugt, das temporary, was im operator + entsteht, gleich im speicher von c konstruieren und so den aufruf von copy-c'tor bzw. operator = überflüssig machen.

    besser implementiert man + nat., wie shade schon gezeigt hat, mittels +=

    class Betrag {
    public:
        double wert;
        std::string bez;
    
    public:
    
        Betrag();
        Betrag(double y) : wert( y ) { }
    /*    Betrag (const Betrag& abc) {
    		wert = abc.wert;
    		bez =abc.bez;
    	}*/
        Betrag& operator+=( const Betrag& rhs ) {
            wert += rhs.wert;
            return *this;
        }
    };		
    const Betrag operator+(Betrag lhs, const Betrag& rhs) {
        return lhs += rhs;
    }
    

    ganz nebenbei kann man jetzt wert ohne probleme private machen, ohne gleichzeitig + als friend deklarieren zu müssen.



  • Shade Of Mine schrieb:

    3 seiten und nicht einmal die richtige op+ implementierung 😞

    T operator+(T a, T const& b)
    {
      a+=b;
      return a;
    }
    

    so baue ich idr meinen op+ 🙂

    schoen kurz, nicht?

    ja, sowas leuchtet mir irgendwie ein...
    nur leider funktioniert das bei mir nicht... 😞

    Betrag operator+(Betrag b1, Betrag const& b2)
    	 {
    		b1+=b2;
    		return b1;
    	 }
    

    no match for 'operator+=' in 'b1 += b2' -> kommt als Fehlermeldung...



  • camper hat die Lösung doch schon gesagt.
    Du musst auch den +=-Operator überladen.



  • Shade Of Mine schrieb:

    T operator+(T a, T const& b)
    {
      a+=b;
      return a;
    }
    

    Hat das irgendwelche Vorteile gegenüber

    T operator+(T a, T const& b)
    {
      return a+=b;
    }
    

    ?



  • finix schrieb:

    Hat das irgendwelche Vorteile gegenüber

    Ich finds schoener 🙂
    Ich mag Zuweisung im return nicht.

    Aber das ist absolute geschmackssache und dein Code ist kein bisschen schlechter.



  • Jetzt passt der operator endlich 🙂 vielen dank....

    ....
    
    Betrag();
    	Betrag(double y);
    
    	Betrag& operator+=(const Betrag b2)
    	{
    	wert+=b2.wert;
    	return *this;
    	}
    
    };		
    	const Betrag operator+(Betrag b1, const Betrag& b2)
    	 {
    		return b1+=b2;
    	 }
    
    	Betrag::Betrag(double y){
    		wert=y;
    	}
    

    aber wie kannich jetzt die beiden Strings vergleichen?
    so dass die bezeichnungen der beiden zu addierenden beträgen
    übereinstimmen? ich kenn nur strcpy. geschieht der vergleich
    im überladenen Konstruktor+ ?



  • [cpp]
    Betrag& operator+=(const Betrag**&** b2) // <--- hier sollte ne ref hin
    {
    wert+=b2.wert;
    return *this;
    }
    [/cpp]

    schmitti schrieb:

    aber wie kannich jetzt die beiden Strings vergleichen?

    Mit den ganz normalen Vergleichsoperatoren, die sind beim std::string überladen.

    schmitti schrieb:

    ich kenn nur strcpy.

    Hat aber nichts mit Vergleichen zu tun - wenn schon dann strcmp.

    schmitti schrieb:

    geschieht der vergleich
    im überladenen Konstruktor+ ?

    Wäre fast sinnvoll wenn du verschiedenen Währungen o.ä. hast, meinst du nicht? 😉



  • mein String-Vergleich, der die Bezeichnungen überprüft und bei gleicher Bezeichnung dann die werte addiert sieht mal so aus:

    const Betrag operator+(Betrag b1, const Betrag& b2)
    	 {
    		if (b1.bez==b2.bez)
    		return b1+=b2;
    		else
    		{ 
    			cout<<"fehler";
    		}
    	 }
    

    Passt das so? 😕



  • schmitti schrieb:

    mein String-Vergleich, der die Bezeichnungen überprüft und bei gleicher Bezeichnung dann die werte addiert sieht mal so aus:

    const Betrag operator+(Betrag b1, const Betrag& b2)
    	 {
    		if (b1.bez==b2.bez)
    		return b1+=b2;
    		else
    		{ 
    			cout<<"fehler";
    		}
    	 }
    

    Passt das so? 😕

    Nö, weil du im else-Zweig nichts zurückgibst.



  • Hab mich über noch ein ähnliche Klasse gestürzt...
    Hier gehts auch hauptsächlich ums Überladen von Operatoren...

    Würd gern wissen, ob die klasse stimmt, also ob grobe fehler drinnen sind..

    class Fahrrad 
    {
       public:	
    
    	std::string sponsor;
    	std::string farbe;
    	double kmstand;
    	bool defekt;	
    
       public:	
    	void print();
    	void unfall();
    	void reparatur();
    
    	Fahrrad(string spons);
    	Fahrrad(string spons, string f);
    	Fahrrad(string spons, string f, bool is_defekt);
    
    	Fahrrad operator+=(const Fahrrad& f2)
    	{
    		kmstand+=f2.kmstand;
    		return *this;
    	}
    
    	~Fahrrad();
    
    };
    	Fahrrad::Fahrrad(string spons)
    	{ 
    		sponsor=spons;
    	}
    
    	Fahrrad::Fahrrad(string spons, string f)
    	{
    		sponsor=spons;
    		farbe=f;
    	}
    
    	Fahrrad::Fahrrad(string spons, string f, bool isdefekt)
    	{
    		sponsor=spons;
    		farbe=f;
    		defekt=isdefekt;
    	}
    
    	void Fahrrad::print()
    	{
    		cout << "Sponsor: " << sponsor <<endl;
    		cout << "Farbe: " << farbe<<endl;
    			if (defekt)
    			cout <<"kaput"<<endl;
    	}
    
    	void Fahrrad::reparatur()
    	{
    		kmstand = 0;  //nach der Reparatur wird kmstand auf 0 gesetzt
    	}
    
    	const Fahrrad operator+(Fahrrad f1, const Fahrrad& f2)
    	{
    	return f1+=f2;
    	}
    

    hab nur ein problem:

    der kilometerstand soll nur dann erhöht werden, wenn das fahrrad
    funktionstüchtig ist...im konstrukter kennt er das bool isdefekt ja leider
    nicht...deshalb weiß ich nicht, wie ich die überprüfung machen soll..

    weiß das jemand?

    noch eine zweite Frage:
    bei einer zahl zb 18,45 ...wie komme ich zu den ,45?



  • void reparatur();
    

    Das ist zwar eine reine Stillfrage allerdings tut ein Objekt ja was wenn eine Methode aufgerufen wird. Also wird man es eher mit einem Verb als mit einem Dingwort in Verbindung bringen.

    Fahrrad operator+=(const Fahrrad& f2)
    {
      kmstand+=f2.kmstand;
      return *this;
    }
    

    Du solltest eine non const Reference zurückgeben. Wie sollen sonst solche Konstrukte funktioniren:

    a+=b+=c;
    
    Fahrrad(string spons);
    Fahrrad(string spons, string f);
    Fahrrad(string spons, string f, bool is_defekt);
    

    Mach daraus mal

    Fahrrad(string spons, string f="", bool is_defekt=false);
    

    Und dann wirfst du die Definitionen für Fahrrad(string spons); und Fahrrad(string spons, string f); weg. Wichtig die default Werte für die Parameter nicht in der Definition wiederholen.

    ~Fahrrad();
    

    Ziemlich überflüssig nicht?



  • dein problem mit dem überladenen operator:

    du willst quasi a=a+b; "rechnen"

    also in der Deklaration (auszug):
    float wert;
    betrag operator+(const betrag &rhs);
    betrag operator=(const betrag &rhs);
    //konstruktor
    betrag(const float &rhs);
    betrag(const betrag &rhs);

    Definition:

    betrag betrag::operator+(const betrag &rhs)
    {
    return(betrag(wert+rhs.wert));
    }
    betrag betrag::operator=(const betrag &rhs)
    {
    wert=rhs.wert;
    return(betrag(rhs));
    }

    betrag::betrag(const float &rhs)
    {
    wert=rhs;
    }

    betrag::betrag(const betrag &rhs)
    {
    wert=rhs.wert;
    }

    vorteil:

    a=b möglich
    a=a+b möglich
    c=a=a+b auch möglich

    ciao


Anmelden zum Antworten