Operatoren Überladen
-
Hallo,
kann mir einer von euch erklären, wann ich Operatoren global oder per Elementunktion überlade und warum?
Hab mir das zwar angeguckt aber verstehe es nicht so richtig ... plz Help me
thx im voraus
-
Ich würde sagen man macht den Operator dann global, wenn der 1. Operand auch einen anderen Typ als *this besitzen soll.
-
Hallo,
ich werde's dir am Beispiel einer Wrapper-Klasse für ints erlären:
#include <iostream> using namespace std; class Integer { int value; public: //Ctors, Dtor Integer(int i=0) : value(i) {} Integer(const Integer &rhs) : value(rhs.value) {} ~Integer() {} int getValue() const { return value; } void setValue(int i) { value = i; } //Zuweisungs-Op Integer& operator=(const Integer &rhs) { if (&rhs == this) //Selbstzuweisung? return *this; value = rhs.value; return *this; } //Bauen wir den + Op mal als member ein, und sehen was passiert: Integer operator+(const Integer &rhs) { return Integer(this->value + rhs.value); } }; //Global-überladener Ausgabe-Op, erstmal unwichtig ostream& operator<<(ostream &os, const Integer &i) { return os<<i.getValue(); } int main() { Interger i(5), j(7), result(0); //Drei Integer instanziert result = i + j; //Klappt, da beide Operatoren vom Typ Integer sind, eigentlicher Aufruf i.operator+(j) result = i + 9; //Klappt, erster Operand vom Typ Integer, zweiter vom Typ int, der wird (implizit) über den ersten Ctor in //ein Integer konvertiert, eigentlicher Aufruf lautet: i.operator+(Integer(9)) result = 9 + j; //uh oh, klappt nicht, da 9 nicht vom Typ Integer ist, ausgeschrieben bedeutet dieser Aufruf nämlich: 9.operator+(j) !! result = 1 + 2; //Klappt, weil der eingebaute + operator benutzt wird ;-) return 0; }Du siehst also, implementieren wir den + Op als Memberfunktion, muss unser linker Operand vom Typ Integer sein.
Abhilfe schafft hier die globale Überladung:
#include <iostream> using namespace std; class Integer { int value; public: //Ctors, Dtor Integer(int i=0) : value(i) {} Integer(const Integer &rhs) : value(rhs.value) {} ~Integer() {} int getValue() const { return value; } void setValue(int i) { value = i; } //Zuweisungs-Op Integer& operator=(const Integer &rhs) { if (&rhs == this) //Selbstzuweisung? return *this; value = rhs.value; return *this; } }; //Jetzt global: Integer operator+(const Integer &lhs, const Integer &rhs) { return Integer(lhs.getValue()+rhs.getValue()); }; //Global überladener Ausgabe-Op, erstmal unwichtig ostream& operator<<(ostream &os, const Integer &i) { return os<<i.getValue(); } int main() { Interger i(5), j(7), result(0); //Drei Integer instanziert result = i + j; //Klappt, da beide Operatoren vom Typ Integer sind, eigentlicher Aufurf: operator+(i,j) result = i + 9; //Klappt, eigentlicher Aufruf lautet: operator+(i, Integer(9)) result = 9 + j; //Klappt, eigentlicher Aufruf: operator+(Integer(9),j) result = 1 + 2; //Klappt, ruft den eingebauten + op für int's auf (Greetz @ CStoll :D ) return 0; }Somit können wir den + Op auch benutzen, wenn der linke (oder beide) Operand(en) nicht vom Typ Integer sind.
MfG
GPC
-
-
Dieser Thread wurde von Moderator/in kingruedi aus dem Forum Rund um die Programmierung in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
GPC schrieb:
result = 1 + 2; //Klappt, eigentlicher Aufruf: operator+(Integer(1), Integer(2))Falsch - das klappt schon, ruft aber definitiv nicht deinen operator+ auf, sondern den vordefinierten operator+ für int's (und anschließend den operator= und int-Ctor deiner Klasse - result.operator=(Integer(1+2));).
-
CStoll (off) schrieb:
GPC schrieb:
result = 1 + 2; //Klappt, eigentlicher Aufruf: operator+(Integer(1), Integer(2))Falsch - das klappt schon, ruft aber definitiv nicht deinen operator+ auf, sondern den vordefinierten operator+ für int's (und anschließend den operator= und int-Ctor deiner Klasse - result.operator=(Integer(1+2));).
öh, hast recht. Da wird natürlich der built-in op für int's aufgerufen. War wohl so im op-Überladen drin, dass mir das nicht aufgefallen ist

gleich mal ändern gehn...