Operator Overloading <<



  • Hi!

    Ich würde gerne den <<-Operator überladen. Folgende Situation:

    Ich habe unter anderem die Klassen Game und Player. Ich würde den <<-Operator gerne so überladen, dass ich in der Game.cpp nach std::cout << player; eine Memberfunktion der Playerklasse aufgerufen wird (also das Ganze zu std::cout << player.getName() wird).

    Wie mache ich das? Wo muss ich die Überladung definieren? Bisheriger Stand:

    In der Game-Klasse:

    Deklaration im Headerfile:

    friend std::ostream& operator<<(std::ostream &os, const ChessPlayer& pl);
    

    Im .cpp-File:

    std::ostream& ChessGame::operator<<(std::ostream& os, const ChessPlayer& pl)
    {
      pl.fullNameToStream(os);
      return os;
    }
    

    In der Player-Klasse:

    Deklaration im Header-File:

    void fullNameToStream(std::ostream&) const;
    

    Im .cpp-File:

    void ChessPlayer::fullNameToStream(std::ostream&) const
    {
      std::cout << getFullName();
    }
    

    Edit:
    Das liefert mir bei der Ausführung von std::cout << player den Fehler "error: no match for 'operator<<' in 'std::cout << player'.

    Liebe Grüße



  • Du hast den << - Operator IN der Klasse überladen ? Du musst ihn außerhalb der Klasse überladen, genauso wie du es gerade getan hast - nur eben nicht in der Klasse. Du hast in Klassen immer noch ein weiteres Argument, this-pointer eben. Das siehst du selber zwar nicht direkt, aber der compiler.



  • Aber irgendwo muss ich noch einen Fehler haben, denn wenn ich die Überladung als Member in der Playerklasse deklariere, klappt es auch nicht:

    Headerfile:
    std::ostream& operator<<(std::ostream& os);
    
    .cpp-File:
    std::ostream& ChessPlayer::operator<<(std::ostream& os)
    {
      os << getFullName();
      return os;
    }
    

    Das müsste ja eigentlich auch klappen, es kommt allerdings "error: no match for 'operator<<' in 'std::cout << player'".



  • WurzelAusZwei schrieb:

    friend std::ostream& operator<<(std::ostream &os, const ChessPlayer& pl);
    

    Ohne "friend" wäre das die Deklaration einer Memberfunktion. (Dann würde der Compiler allerdings auch sempern, weil ein Member operator << nur einen Parameter nehmen kann, nämlich den rechten Operanden).

    Mit "friend" ist es allerdings die Deklaration einer freien Funktion, die im Namespace lebt der auch die Klasse ChessGame enthält.

    WurzelAusZwei schrieb:

    std::ostream& ChessGame::operator<<(std::ostream& os, const ChessPlayer& pl)
    {
      pl.fullNameToStream(os);
      return os;
    }
    

    Und das hier ist der Versuch eine Memberfunktion ChessGame::operator << zu implementieren.
    Die wurde aber nicht deklariert - du hast ja nur mit "friend" eine freie Funktion deklariert.

    Also => mach einfach das "ChessGame::" weg, und es sollte passen.



  • WurzelAusZwei schrieb:

    Aber irgendwo muss ich noch einen Fehler haben, denn wenn ich die Überladung als Member in der Playerklasse deklariere, klappt es auch nicht:

    Headerfile:
    std::ostream& operator<<(std::ostream& os);
    
    .cpp-File:
    std::ostream& ChessPlayer::operator<<(std::ostream& os)
    {
      os << getFullName();
      return os;
    }
    

    Das müsste ja eigentlich auch klappen, es kommt allerdings "error: no match for 'operator<<' in 'std::cout << player'".

    Jo, das kann auch nicht funktionieren.
    Mit std::ostream& operator<<(std::ostream& os); in der Klasse deklarierst du ja einen operator << der linkerhand nen ChessPlayer nimmt und rechterhand nen ostream .

    Den müsstest du dann mit player << std::cout aufrufen, also genau verkehrt herum.

    Genau das ist auch der Grund warum man "Stream-Operatoren" nicht als Member machen kann. Weil die Reihenfolge der Operanden nicht passt.



  • Jetzt hab ich's verstanden, vielen Dank!



  • Ohne Eigenwerbugn machen zu wollen, wir haben Artikel zur Operatorüberladung im Magazin: http://magazin.c-plusplus.net/artikel/�berladung von Operatoren in CPlusPlus (Teil 1)


Anmelden zum Antworten