Zum Inhalt springen

überladenen operator<< und +


Armini

Empfohlene Beiträge

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 von Armini
Link zu diesem Kommentar
Auf anderen Seiten teilen

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 Zuweisungen
  • Implementiere deinen Op= mittels Copy&Swap
  • Eine Using-Direktive im Header ist keine gute Idee
  • Return ist keine Funktion, lass die Klammern weg.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.B); } //--------------------------------------------------------------------------- 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 von Armini
Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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+=B) << endl;

geht's.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...