Armini Geschrieben 19. Mai 2010 Geschrieben 19. Mai 2010 (bearbeitet) Hallo, ich habe eine kleine Beispielklasse geschrieben die zwei Integerwerte a und b enthält. Ein überladener Operator + addiert die beiden Werte. Wenn ich eine Instanz mit dem ebenso überladenen operator << einzeln ausgebe, funktioniert das bestens, aber wenn ich einen Ausdruck a+b ausgeben will, gibt es die Meldung "no match for 'operator<<' in 'std::cout << MyClass::operator+(const MyCl.........". Würde mich über einen Tipp zur Lösung freuen. Code liegt bei (Qt Creator mit Gnu c++) Danke und Gruß Armin //-------------------------------------------------------- //myclass.h: //-------------------------------------------------------- #ifndef MYCLASS_H #define MYCLASS_H #include <fstream> #include <iostream> using namespace std; class MyClass { public: MyClass(const MyClass &A); MyClass(int a, int ; ~MyClass(); MyClass& operator= (const MyClass &A); const MyClass operator+ (const MyClass &A) const; friend ostream& operator<< (ostream &out, MyClass &A); private: int a; int b; }; #endif // MYCLASS_H [/code] [code] //-------------------------------------------------------- //myclass.cpp: //-------------------------------------------------------- #include "myclass.h" //--------------------------------------------------------------------------- MyClass::MyClass(const MyClass &A) { a = A.a; b = A.b; } //--------------------------------------------------------------------------- MyClass::MyClass(int aa, int bb) { a = aa; b = bb; } //--------------------------------------------------------------------------- MyClass::~MyClass() { } //--------------------------------------------------------------------------- ostream &operator<<(ostream &out, MyClass &A) { cout << A.a << ", " << A.b << endl; return(out); } //--------------------------------------------------------------------------- MyClass& MyClass::operator=(const MyClass &A) { if (this != &A) { a = A.a; b = A.b; } return(*this); } //--------------------------------------------------------------------------- const MyClass MyClass::operator+(const MyClass& A) const { MyClass R(*this); R.a += A.a; R.b += A.b; return(R); } //-------------------------------------------------------- //main.cpp: //-------------------------------------------------------- #include "myclass.h" int main(int argc, char *argv[]) { MyClass a(3, 3), b(2, 3); cout << a << b; MyClass c = a + b; cout << c; // Als nächstes kommt die "Problemzeile" -> Compiler Fehlermeldung: // main.cpp:11: error: no match for 'operator<<' in 'std::cout << ... // ...MyClass::operator+(const MyClass&) const(((const MyClass&)((const .. // ...MyClass*)(& )))' cout << a + b; // Was ist hier falsch?? return(0); } [/code] Bearbeitet 19. Mai 2010 von Armini Zitieren
Klotzkopp Geschrieben 19. Mai 2010 Geschrieben 19. Mai 2010 Dein Operator+ gibt ein const-Objekt zurück, was auch richtig ist. Dein Operator<< will aber ausdrücklich ein MyClass &A, also nicht const. Du kannst kein const-Objekt übergeben, wo ein nicht-const-Objekt gefordert ist. Andererseits ist es natürlich so, dass dein Operator<< das MyClass-Objekt nicht ändert, also auch prima mit einem const-Objekt arbeiten könnte. Darum ändere einfach den Parametertypen auf const MyClass &. Ein paar Anmerkungen: Benutz in den Konstruktoren Initialisierungslisten statt ZuweisungenImplementiere deinen Op= mittels Copy&SwapEine Using-Direktive im Header ist keine gute IdeeReturn ist keine Funktion, lass die Klammern weg. Zitieren
Armini Geschrieben 20. Mai 2010 Autor Geschrieben 20. Mai 2010 (bearbeitet) Hallo Klotzkopp, ersteinmal vielen Dank für die Hilfe und besonders für die weiterführenden Tipps. Es funktioniert jetzt. Zu zwei Dingen habe ich noch eine Frage / Anmerkung using namespace std Stimmt, im Headerfile ist das nicht geschickt, allerdings muss ich dann wenigstens "using std::ostream" angeben weil die Angabe von std::ostream in der Definition selbst wieder eine Fehlermeldung bringt.Initialisierungslisten In dem einfachen Beispiel geht das, aber die eigentliche Klasse besitzt auch ein Array, ist es dann sinnvoll trotzdem die Basistypen in einer Initialisierungsliste anzugeben und nur das Array im Rumpf des Construktirs zu definieren? (Hier soll Platz für eine Matrix reserviert werden die a*b Elemente hat).nochmal cout Wenn ich einen operator += definiere, dann gibt dieser void zurück, ist es prinzipiell auch möglich irgendwie cout << A+=B auszugeben, oder schreibt man das einfach in zwei Zeilen? Viele Grüße Armin //---------- // myclass.h //---------- #ifndef MYCLASS_H #define MYCLASS_H #include <fstream> #include <iostream> using std::ostream; class MyClass { public: MyClass(const MyClass &A); MyClass(int a, int ; ~MyClass(); void swap(MyClass & other); MyClass& operator= (const MyClass &A); const MyClass operator+ (const MyClass &A) const; friend ostream& operator<< (ostream &out, const MyClass &A); private: int a; int b; }; #endif // MYCLASS_H [/code] [code] //---------- // myclass.cpp //---------- #include "myclass.h" using namespace std; //--------------------------------------------------------------------------- MyClass::MyClass(const MyClass &A) { a = A.a; b = A.b; } //--------------------------------------------------------------------------- MyClass::MyClass(int aa, int bb) : a(aa), b(bb) { } //--------------------------------------------------------------------------- MyClass::~MyClass() { } //--------------------------------------------------------------------------- ostream &operator<<(ostream &out, const MyClass &A) { cout << A.a << ", " << A.b << endl; return out; } //--------------------------------------------------------------------------- void MyClass::swap(MyClass & other) { std::swap(a, other.a); std::swap(b, other.; } //--------------------------------------------------------------------------- MyClass& MyClass::operator=(const MyClass &A) { if (this != &A) { MyClass Temp(A); swap(Temp); } return *this; } //--------------------------------------------------------------------------- const MyClass MyClass::operator+(const MyClass& A) const { MyClass R(*this); R.a += A.a; R.b += A.b; return R; } Bearbeitet 20. Mai 2010 von Armini Zitieren
Klotzkopp Geschrieben 20. Mai 2010 Geschrieben 20. Mai 2010 Initialisierungslisten In dem einfachen Beispiel geht das, aber die eigentliche Klasse besitzt auch ein Array, ist es dann sinnvoll trotzdem die Basistypen in einer Initialisierungsliste anzugeben und nur das Array im Rumpf des Construktirs zu definieren? (Hier soll Platz für eine Matrix reserviert werden die a*b Elemente hat).Arrays kannst du nicht in einer Initialisierungsliste initialisieren, das ist richtig. Trotzdem solltest du eine solche Liste, soweit möglich, benutzen. Bei komplexeren Membern (wie z.B. Klassenobjekten) kann eine direktive Initialisierung erheblich einfacher sein als eine Default-Initialisierung mit anschließender Zuweisung. Bei const-Membern und Referenzen geht es gar nicht anders. Wenn dein a*b übrigens erst zur Laufzeit feststeht, hilft dir ein Array sowieso nicht weiter. nochmal cout Wenn ich einen operator += definiere, dann gibt dieser void zurück, ist es prinzipiell auch möglich irgendwie cout << A+=B auszugeben, oder schreibt man das einfach in zwei Zeilen?Lass den Operator einfach nicht void, sondern MyClass& zurückgeben (und dann natürlich *this als Rückgabewert). Die Prüfung auf Selbstzuweisung im Op= könntest du weglassen, die frisst vermutlich mehr Performance, als sie einspart, denn Selbstzuweisung ist sehr selten. Außerdem macht sie deinen Op= wieder Exception-unsicher(er), weil der Adressoperator überladbar ist, und damit werfen könnte. Zitieren
Armini Geschrieben 20. Mai 2010 Autor Geschrieben 20. Mai 2010 Vielen Dank, cout << a+=b << endl; erzeiugt zwar wieder error: no match for 'operator+=' in 'operator<<(((std::ostream&)(& out.std::basic_ofstream<char, std::char_traits<char> >::<anonymous>)), ((const Matrix&)((const Matrix*)(& a)))) += b' aber geklammert cout << (a+= << endl; geht's. Zitieren
Klotzkopp Geschrieben 20. Mai 2010 Geschrieben 20. Mai 2010 aber geklammert cout << (a+= << endl; geht's.Das liegt an der Operatorbindungsstärke, das würde dir auch mit ints passieren. << bindet stärker als +=, das Klammern ist hier also unvermeidlich. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.