Operatorüberladung
-
Hi, ich bin gerade dabei eine Klasse für rationale Zahlen zu schreiben, dabei sollen die 4 Grundrechenarten implementiert werden. Das wollte ich mit überladenen Operatoren machen. Bei operator+ mache ich allerdings was verkehrt. der Compiler schreibt mir:
|59|error: 'Rn Rn::operator+(Rn, Rn)' must take either zero or one argument/* Entwerfen Sie einen ADT für rationale Zahlen. Implementieren Sie neben einem sinnvollen Konstruktor sowie Setter- und Getter-Methoden folgende Operationen: - Rückgabe des Dezimalwerts einer rationalen Zahl - weitestgehendes Kürzen der rationalen Zahl - Implementieren der vier Grundrechenarten Geben Sie dafür die Schnittstellen an und implementieren Sie den ADT! */ #include <iostream> using namespace std; class Rn{ private: int numerator; //Zähler int denominator; //Nenner int gcd(int a, int b){ //greatest common divisor if (a < 0) a *= -1; if (b < 0) b *= -1; if (a == 0 || b == 0) return 1; if (a < b) return gcd(a, b-a); if (a > b) return gcd(a-b, b); else return a; } void reduce_rationalNumber() { int factor = gcd(numerator, denominator); numerator /= factor; denominator /= factor; } public: Rn() { numerator = 0; denominator = 1; } int get_numerator() { return numerator; } int get_denominator() { return denominator; } void set_rationalNumber() { cout <<"\nNumerator: "; cin >> numerator; int d; //Kontrollvariable damit Division durch 0 verhindert wird do { cout <<"Denominator: "; cin >> d; if ( d == 0 ) cout << "Not defined, enter again.\n"; } while (d == 0); denominator = d; reduce_rationalNumber(); } void get_rationalNumber() { cout <<"\n" << numerator << "/" << denominator; } void decimalValue() { cout << "\nDecimal: " << (numerator * 1.0) / (denominator * 1.0); } Rn operator+(const Rn a, const Rn b){ // a/b + c/d = (ad + bc) / bd Rn temp; temp.numerator = a.get_numerator() * b.get_denominator() + a.get_denominator * b.get_numerator(); temp.denominator = a.get_denominator * b.get_denominator; return temp; }/* Rn operator-(Rn a, Rn b){ } Rn operator*(Rn a, Rn b){ } Rn operator/(Rn a, Rn b){ } */ }; int main() { Rn a, b; Rn c; a.set_rationalNumber(); a.get_rationalNumber(); a.decimalValue(); return 0; }
-
Wenn du die Operatoren als Klassen-Methode überlädst, dann mußt du nur einen Parameter entgegennehmen - als linker Operand wird *this verwendet.
-
Wenn du operator+ innerhalb der Klasse deklarierst, ist der erste Parameter durch this bereits implizit vorgegeben. Du kannst also die Parameterzahl auf 1 reduzieren oder (besser) den operator+ als freie Funktion definieren.
BTW: Wenn du null Parameter hättest (was der Compiler dir zusätzlich vorschlägt), würdest du den unären operator+ überladen.
-
siehe zum Thema Operator-Überladung auch:
Überladung von Operatoren in C++ (Teil 1)Teil 2 und Teil 3 sind in diesem Beitrag auch verlinkt.
-
Wo die eigentliche Frage jetzt beantwortet ist: Den Setter solltest Du auch nochmal überdenken. Erstens nimmt ein Setter normalerweise Parameter entgegen und liest nicht von cin. Zweitens ist so eine Rational-Klasse doch das Paradebeispiel für eine Wert- (und damit immutable-)Klasse, das heisst, eigentlich sollte es überhaupt keine Setter geben.
-
inter2k3 schrieb:
siehe zum Thema Operator-Überladung auch:
Überladung von Operatoren in C++ (Teil 1)Teil 2 und Teil 3 sind in diesem Beitrag auch verlinkt.
Teil 2 und 3 zeigen eine komplette Rational-Klasse mit allen Operatoren, die man sich dafür nur wünschen kann. Voraussetzung ist boost.Operators
-
Vielen Dank für die Hilfe. Mein Programm sieht jetzt folgendermaßen aus:
#include <iostream> using namespace std; class Rn{ private: int numerator; //Zähler int denominator; //Nenner int gcd(int a, int b){ //greatest common divisor if (a < 0) a *= -1; if (b < 0) b *= -1; if (a == 0 || b == 0) return 1; if (a < b) return gcd(a, b-a); if (a > b) return gcd(a-b, b); else return a; } void reduce_rationalNumber() { int factor = gcd(numerator, denominator); numerator /= factor; denominator /= factor; } public: Rn() { numerator = 0; denominator = 1; } Rn(int n, int d) { this->numerator = n; this->denominator = d; } int get_numerator() const { return numerator; } int get_denominator() const { return denominator; } void set_numerator(int n) { this->numerator = n; } void set_denominator(int d) { this->denominator = d; } void get_rationalNumber() const { cout <<"\n" << numerator << "/" << denominator; } void decimalValue() const { cout << "\nDecimal: " << (numerator * 1.0) / (denominator * 1.0); } }; Rn operator+(Rn& a, Rn& b) { // a/b + c/d = (ad + bc) / bd Rn temp; temp.set_numerator(a.get_numerator() * b.get_denominator() + a.get_denominator() * b.get_numerator()); temp.set_denominator(a.get_denominator() * b.get_denominator()); return temp; } Rn operator-(Rn& a, Rn& b) { // a/b - c/d = (ad - bc) / bd Rn temp; temp.set_numerator(a.get_numerator() * b.get_denominator() - a.get_denominator() * b.get_numerator()); temp.set_denominator(a.get_denominator() * b.get_denominator()); return temp; } Rn operator*(Rn& a, Rn& b) { // a/b * c/d = ac / bd Rn temp; temp.set_numerator(a.get_numerator() * b.get_numerator()); temp.set_denominator(a.get_denominator() * b.get_denominator()); return temp; } Rn operator/(Rn& a, Rn& b) { // a/b / c/d = ad / bc Rn temp; temp.set_numerator(a.get_numerator() * b.get_denominator()); temp.set_denominator(a.get_denominator() * b.get_numerator()); return temp; } int main() { Rn a(-1,2), b(1,2); Rn c = a+b; c.get_rationalNumber(); c.decimalValue(); return 0; }
Bin mir nicht ganz sicher wo noch überall ein const fehlen könnte.
-
int gcd(int a, int b){ //greatest common divisor if (a < 0) a *= -1; if (b < 0) b *= -1; // if (a == 0 || b == 0) return 1;//falsch, oder? if (a == 0 ) return b; // if (b == 0 ) return a;//kommt eh nicht vor if (a < b) return gcd(a, b-a); if (a > b) return gcd(a-b, b); else return a; }