Operatorüberladung für / mit 2 Argumenten
-
Hallo!
Ich hab als Anfänger mal eine (ich denke) eher simple Frage. Hab auf die schnelle nichts in der FAQ gefunden, deshalb poste ich mal.
Also ich hab die Klasse Bruch definiert und will jetzt sowas in der Art schreiben können:
Bruch b;
b=5/6;Da macht der GCC nur leider nicht mit... hier ist der ganze Quelltext:
#include <iostream> using std::cin; using std::cout; using std::endl; template <class T> class vector { private: int m_anz_elemente; T *p; public: vector(int anz_elemente) { m_anz_elemente = anz_elemente; p = new T[m_anz_elemente]; }; T &operator[](int index) { return p[index]; }; void ausgabe(int index) { cout << p[index] << endl; }; }; class Bruch { private: int m_zaehler; int m_nenner; public: Bruch(int zaehler, int nenner) { m_zaehler = zaehler; m_nenner = nenner; }; Bruch() {m_zaehler = 0; m_nenner = 0; }; Bruch operator = (Bruch val) { return val; }; }; Bruch operator /(int z, int d) { Bruch d(z, d); return d; } int main() { cout << "Hello World!" << endl; int a = 3; Bruch b(5, 6); vector <int> v1(a); vector <Bruch> b1(5); b1[5] = (5/6) cout << v1[1] << endl; return 0; };Ich hoff irgendjemand findet sich da drin zurecht :-). Das Problem ist halt, dass ich auf jeden Fall 2 Argumente für die Funktion "Operator /" haben muss. Der Compiler meckert dann aber:
52: error: ‘Bruch operator/(int, int)’ must have an argument of class or enumerated type
Tja und was das heißen soll weiß ich auch nicht....
-
Also...
Der Operator / ist ein binärer Operator, sprich er besitzt 2 Operanden.
Wenn du in deiner Klasse den Operator überlädtst, ist der 1.Operand automatisch die aufgerufene Klasseninstanz.
In menschlichen Worten:
Wenn ich schreibe ob1 / ob2, dann wird der Funktion (in der Klasse "Ob")
Ob Ob::operator/(Ob objekt)
ob1 als erster Operand übergeben. (Wenn dus genau wissen willst: And die Funktion wird ob1 über den impliziten this-Zeiger übergeben. Also im obigen Bsp. wird an die Funktion übergeben: this, ob2 (<-nicht ganz richtig) , wobei this einfach der linke Operand ist. Es wird immer der linke Operand per this übergeben. )Das heißt, deine Funktionsdefinition wird nie funktionieren, weil die Funktion mit operator/ immer als linken Operanden ein Objekt der Klasse Bruch erwarten wird.
Bei deinem Beispiel müsstest du den int-operator/ überladen, und ich zweifle, dass das möglich ist.
Du könntest höchstens den operator= für double überladen, und irgendwie schaun, dass du die double mit einer Zahl multiplizierst, bis du zwei ganze Zahlen hast, und die dann in m_zaehler und m_nenner speicherst.
-
Du könntest auch operator= für char* überladen, damit du sowas machen kannst
Bruch zahl = "5/6";
-
Braunstein schrieb:
Du könntest auch operator= für char* überladen, damit du sowas machen kannst
Bruch zahl = "5/6";Mit dem Bsp. meinst du wohl eher den Copy-C'tor

rocky16 schrieb:
...
Bruch operator /(int z, int d) { Bruch d(z, d); return d; }...
Das kann nicht funktionieren, da du hier versuchst die Bedeutung von op/ für einegebaute Datentypen (int) zu ändern ...
Du müsstest schon einen Konstruktor bereitstellen der "x/y" annimmt.
Aber dann auch auf implizte Umwandlung aufpassen.Besser wäre es dann doch es so zu schreiben:
b1[0] = Bruch(x,y);Ist meiner Meinung am sichersten und irgendwie auch schöner als "x/y" in nem Programm zu schreiben

Eine ganz andere Möglichkeit wäre einen Bruch(double z) Konstruktor bereitzustellen und dir dann da aus der Dezimalzahl einen Bruch zu machen.
Dann würde auch sowas wie b1[9] = 4/6; funktionieren, aber dann kommt wieder die Sache mit Implizierter Typumwandlung...
-
Freak_Coder schrieb:
Eine ganz andere Möglichkeit wäre einen Bruch(double z) Konstruktor bereitzustellen und dir dann da aus der Dezimalzahl einen Bruch zu machen.
Dann würde auch sowas wie b1[9] = 4/6; funktionieren, aber dann kommt wieder die Sache mit Implizierter Typumwandlung...
Sagen wir es mal so: Es würde compilieren - aber nicht das richtige Ergebnis liefern. (4/6 wird per int-Arithmetik verrechnet, liefert also 0)
Zum eigentlichen Thema: Wie schon gesagt kannst du Operatoren nur dann überladen, wenn eine deiner eigenen Klassen daran beteiligt ist. Der operator/ für int-Werte ist schon vom Compiler vorgegeben (der liefert einen int) und kann nicht ersetzt werden.
PS: Anstatt eine eigene vector-Klasse zu schreiben solltest du lieber std::vector<> verwenden

PPS: Und die Ctor'en der Bruch-Klasse würde ich zusammenfassen zu:
Bruch(int z=0,int n=1) : m_zaehler(z),m_nenner(n) {}
-
CStoll schrieb:
Es würde compilieren - aber nicht das richtige Ergebnis liefern. (4/6 wird per int-Arithmetik verrechnet, liefert also 0)
Sry stimmt. Habe ich nicht beachtet
