[Gelöst] Probleme beim Überladen von Operatoren
-
manni66 schrieb:
Im Primer steht aber noch ein friend davor, oder?
Ja aber nur vor ostream und istream.
sonst nirgends.
-
Wenn du die Funktionen als Memberfunktionen deklarierst, wird ein this Parameter hinzugefügt.
Dein operator + wird alsoComplex& operator + (Complex* this, const Complex&, const Complex&);Was natürlich keinen Sinn macht. Du musst dich zwischen Membern und freien Funktionen entscheiden, wobei ich freien Funktionen hier den Vorzug geben würde. Und operator + gibt kein Complex& sondern ein Complex zurück. (Und dass es std::complex gibt ist dir hoffentlich klar. ;))
-
Dann ist es wohl ein Fehler. So wie du es in der Klassendefinition geschrieben hst, handelt es sich um ein Memberfunktion. Die Funktionsdefinition ist aber eine freie Funktion. Das passt nicht zusammen.
-
cooky451 schrieb:
Complex& operator + (Complex* this, const Complex&, const Complex&);Was natürlich keinen Sinn macht. Du musst dich zwischen Membern und freien Funktionen entscheiden, wobei ich freien Funktionen hier den Vorzug geben würde. Und operator + gibt kein Complex& sondern ein Complex zurück. (Und dass es std::complex gibt ist dir hoffentlich klar. ;))
Das mit *this wusste ich nicht, darum ist die Funktion im C++Primer außerhalb der Klasse.

Das mit std::Complex wusste ich nicht, danke für die Info.
Vielen Dank cooky451! Sehr hilfreich

-
Trotzdem noch eine Frage:
Meine Member sind ja private. Wie kann ich auf diese zugreifen in der operator+()Funktion?
-
Zagatho_zero87 schrieb:
Trotzdem noch eine Frage:
Meine Member sind ja private. Wie kann ich auf diese zugreifen in der operator+()Funktion?
Vielleicht schaust du im Buch noch mal nach der Erklärung zu friend.
-
Zagatho_zero87 schrieb:
Meine Member sind ja private. Wie kann ich auf diese zugreifen in der operator+()Funktion?
So wie du auch sonst zugreifen würdest: Über irgendwelche public Member. Mach dir halt getter. Siehe auch http://en.cppreference.com/w/cpp/numeric/complex daran kannst du dich orientieren.
Edit: Und das mit friend für operator + ist keine gute Idee. Irgendwie willst du ja eh auf die einzelnen Teile zugreifen können.
-
Jetzt steh ich aufm Schlauch...
Würdest du mir das mit den gettern erklären?
-
class complex { double real_; double imag_; public: complex(double re = 0.0, double im = 0.0) : real_(re) , imag_(im) {} double real() const { return real_; } double imag() const { return imag_; } }; complex operator + (const complex& lhs, const complex& rhs) { return complex(...); }
-
33 C:\Dev-Cpp\main.cpp no match for 'operator<<' in '(&std::cout)->std::basic_ostream<_CharT, _Traits>::operator<< [with _CharT = char, _Traits = std::char_traits<char>](std::endl [with _CharT = char, _Traits = std::char_traits<char>]) << operator+(((const Complex&)((const Complex*)(&my_Complex_3))), ((const Complex&)((const Complex*)(&my_Complex_1))))'
-
Sorry wegen Vorpost.
OK danke erstmal cooky451.

Ich habs jetzt so gemacht (Bitte sofort kritisieren, wenn der Code eurer Meinung nach unschön ist)
#include <cstdlib> #include <iostream> class Complex{ private: double real; double imaginary; public: friend std::ostream& operator<<(std::ostream&, Complex&); Complex(double rreal, double iimaginary); double get_real() const; double get_imag() const; }; Complex operator+(const Complex&, const Complex&); Complex operator-(const Complex&, const Complex&); int main(int argc, char *argv[]) { Complex my_Complex_1(10.0, 11.1); Complex my_Complex_2(23.23, 3.232); Complex my_Complex_3=my_Complex_1+my_Complex_2; Complex my_Complex_4=my_Complex_1-my_Complex_2; std::cout<<my_Complex_2<<std::endl; std::cout<<my_Complex_1<<std::endl; std::cout<<std::endl<<my_Complex_3<<std::endl; std::cout<<std::endl<<my_Complex_4<<std::endl; system("PAUSE"); return EXIT_SUCCESS; } Complex::Complex(double rreal, double iimaginary) : real(rreal), imaginary(iimaginary){} std::ostream& operator<<(std::ostream&, Complex& a){ std::cout<<a.real<<std::endl<<a.imaginary<<std::endl; } Complex operator-(const Complex& a, const Complex& b){ double lokal_imag_1=a.get_imag(); double lokal_real_1=a.get_real(); double lokal_imag_2=b.get_imag(); double lokal_real_2=b.get_real(); Complex Complex_sum(lokal_real_1-lokal_real_2, lokal_imag_1-lokal_imag_2); } Complex operator+(const Complex& a, const Complex& b){ double lokal_imag_1=a.get_imag(); double lokal_real_1=a.get_real(); double lokal_imag_2=b.get_imag(); double lokal_real_2=b.get_real(); Complex Complex_sum((lokal_real_1+lokal_real_2),(lokal_imag_1+lokal_imag_2)); return Complex_sum; } double Complex::get_imag() const{ return imaginary; } double Complex::get_real() const{ return real; }Die Addition funktioniert. aber... bei der Subtraktion bekomme ich so was raus:
1.#QNAHN
3.343456e+235
Das stimmt natürlich nicht.
1.Warum kommt da so ein Mist heraus?2. Warum kann ich nicht einfach schreiben:
[cpp]
std::cout<<my_Complex_1+my_Complex_2<<std::endl;da kommen ganz kryptische Fehlermeldungen.. a la:
33 C:\Dev-Cpp\main.cpp no match for 'operator<<' in '(&std::cout)->std::basic_ostream<_CharT, _Traits>::operator<< [with _CharT = char, _Traits = std::char_traits<char>](std::endl [with _CharT = char, _Traits = std::char_traits<char>]) << operator+(((const Complex&)((const Complex*)(&my_Complex_3))), ((const Complex&)((const Complex*)(&my_Complex_1))))'
-
Code dazu wäre gut.
Edit: ok, mom.Das const fehlt da. Sollte std::ostream& operator << (std::ostream&, const Complex&) heißen.
-
Ok danke.
Das Problem mit der Subtraktion hat sich erledigt.
Hatte ein return vergessen bei der Funktion.
-
zu 1: da fehlt das return bei der Subtraktion

zu 2: du mußt noch die Ausgabe für deine Complex-Klasse definieren, d.h. den Stream-Operator <<:ostream& operator <<(ostream& os, const Complex& complex) { return os << '(' << complex.get_real() << '+i' << complex.get_imag() << ')'; }Edit: ups, jetzt erst sehe ich daß du den Operator ja implementiert hast (bzw. versuchst hast, da so wie cooky451 schreibt, das const fehlt ;-).
Jedoch solltest du dort niemals direkt nach cout schreiben, sondern immer in den übergebenen Stream - falls du mal dies in eine Datei ausgeben willst, würdest du dich wundern!!!
-
Könnte man es den nicht einfach auch so machen mit dem +-Operator?
Complex& operator+( const Complex& a ) { Complex my_Complex_3( 0,0 ); my_Complex_3.real = a.real+ this->a; my_Complex_3.imaginary = a.imaginary + this->b; return my_Complex_3; }Würde das nicht auch gehen?
MfG
-
Abgesehen davon, dass du eine Referenz auf ein lokales Objekt zurückgibst:
Das Problem von
operator+als Memberfunktion besteht darin, dass die Argumente asymmetrisch behandelt werden. Der linke Operand muss vom TypComplexsein, während der rechte auch durch implizite Konvertierung zustande kommen kann.Gerade komplexe Zahlen sind ein gutes Beispiel hierfür, da sich ein Konstruktor
Complex(double real = 0, double imag = 0);anbietet, welcher eine implizite Konvertierung von
double-Werten ermöglicht. Wäreoperator+ein Member, ergäbe sich folgende Problematik:Complex c(1, 2); double d = 3; c + d // Funktioniert d + c // Fehler: Linker Operand muss Klassentyp haben
-
Hallo Blaubär!
Ich weiß nicht!

Aber ich habs gestern noch ein bisschen verfeinert, was den Stil angeht und habs so gemacht:
Complex operator+(const Complex& a, const Complex& b){ Complex Complex_temp(a.get_real()+b.get_real(), a.get_imag()+b.get_imag()); return Complex_temp; } Complex operator-(const Complex& a, const Complex& b){ Complex Complex_temp(a.get_real()-b.get_real(), a.get_imag()-b.get_imag()); return Complex_temp;Wobei ich deine Lösung auch interessant finde. Werd ich gleich mal ausprobieren.
Danke.

-
Ok, danke. Ich habe aber noch eine kleinen Fehler gemacht. Es muss natürlich this->real und this->imaginary heißten.
MfG
-
Zagatho_zero87 schrieb:
Wobei ich deine Lösung auch interessant finde. Werd ich gleich mal ausprobieren.
Und dann liest du noch mal schnell den Beitrag von Nexus.
Und deine temp-Variablen sind auch, na ja, zumindest Ansichtssache. Zugegeben, für das Kompilat wird das keinen Unterschied machen, aber Übersichtlicher wird das dadurch jetzt nicht gerade, oder? :p
-
Ja übersichtlicher nicht, das stimmt.
Was gefällt dir besser:
DiesComplex operator-(const Complex& a, const Complex& b){ Complex Complex_temp(a.get_real()-b.get_real(), a.get_imag()-b.get_imag()); return Complex_temp; }oder das
Complex operator-(const Complex& a, const Complex& b){ double lokal_imag_1=a.get_imag(); double lokal_real_1=a.get_real(); double lokal_imag_2=b.get_imag(); double lokal_real_2=b.get_real(); Complex Complex_sum(lokal_real_1-lokal_real_2, lokal_imag_1-lokal_imag_2); return Complex_sum; }Da die Summenbildung Complex_sum(...) ist in beiden Fällen ca. gleich lang. Aber es fallen die lokalen Variablen weg.