Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

überladenen operator<< und +

Empfohlene Antworten

Veröffentlicht

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

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.

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

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.

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.

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.