operator<< warum keinen Zugriff trotz friend?



  • Es würde mich sehr wundern, wenn dadurch das Problem gelöst wird, da die friend Funktion ja kein Element der Klasse ist, sondern nur in der Klasse "angemeldet" wird. Von dem her sollte es egal sein, ob die friend Funktion im private oder public Bereich steht. Aber kannst es ja trotzdem versuchen.
    Eine Idee habe ich aber auch nicht. Das einzige was mir aufgefallen ist wie wäre es mit einem Strichpunkt am Ende der Klassendeklaration.

    Gruß Alex



  • @Chew-Z
    Wo friend steht ist vollkommen gleich.

    @Guntpat
    Sind Namensräume im Spiel?



  • Ich verwende lediglich using namespace std; - das public macht natürlich keinen Unterschied, weil die friend-Funktion nicht direkt zur Klasse gehört.
    Den Strichpunkt habe ich beim Kopieren vergessen. 🙂



  • //Team.h
    class Team  
    {
    friend ostream& operator << (ostream& os, const Team& )const; 
    .....
    }
    


  • Es ist immer noch keine Member-Methode und kann daher auch nicht const sein. Sie hat ja auch keinen this-Pointer.



  • Geht das hier:

    class Team  
    {
    friend ostream& operator << (ostream& os, const Team& myTeam)
    {
        cout.setf (ios::left, ios::adjustfield);
        os <<setw(20)<< myTeam.teamName<< ": ";
        cout.setf (ios::right, ios::adjustfield);
        os<<myTeam.matchesPlayed<<"Spiele,";
        os<<setw(3)<<myTeam.gamesWon<<":"<<setw(3)<<myTeam.gamesLost;
        os<<" Saetze und "<<setw(3)<<myTeam.pointsWon<<":";
        os<<":"<<setw(3)<<myTeam.pointsLost<<" Punkte"<<endl;
    
        return os;
    }
    }
    

    Wenn ja dann hast du ein Problem mit der Signatur des operator>>.



  • Du hast recht - inline (also so wie Du es geschrieben hast) funktioniert das ganze, nur wenn ich die Definition in die cpp auslagere, funktioniert es nicht, aber ich verstehe nicht warum?



  • Kann das problem nicht nachvollziehen. Folgender code compiliert mit g++ 3.3.5 einwandfrei.

    #include <iostream>
    using namespace std;
    
    class Team  {
    public:
      Team():x(12) {}
    private:
      int x;
    friend ostream& operator << (ostream& os, const Team& );
    };
    
    ostream& operator << (ostream& os, const Team& myTeam)
    {
       os << myTeam.x;
       return os;
    }
    
    int main() {
       const Team ct;
       Team t;
       cout << ct << endl << t << endl;
       return 0;
    }
    

    Kurt



  • So würde das bei mir auch funktionieren, wenn man alles in eine Datei schreibt, aber beim Auslagern gibt es Probleme, obwohl das eigentlich gehen sollte.



  • habe den code mal aufgeteilt. Funktioniert so auch.

    team.h

    #include <iostream>
    
    class Team  {
    public:
      Team():x(12) {}
    private:
      int x;
    friend std::ostream& operator << (std::ostream& os, const Team& );
    };
    

    team.cpp

    #include "team.h"
    
    std::ostream& operator << (std::ostream& os, const Team& myTeam)
    {
       os << myTeam.x;
       return os;
    }
    

    main.cpp

    #include <iostream>
    #include "team.h"
    using namespace std;
    
    int main() {
       const Team ct;
       Team t;
       cout << ct << endl << t << endl;
       return 0;
    }
    

    wenn ich den code aber folgendermassen aufteile :
    team.h

    class Team  {
    public:
      Team():x(12) {}
    private:
      int x;
    friend ostream& operator << (ostream& os, const Team& );
    };
    

    team.cpp

    #include <iostream>
    #include "team.h"
    
    std::ostream& operator << (std::ostream& os, const Team& myTeam)
    {
       os << myTeam.x;
       return os;
    }
    

    main.cpp wie oben

    dann funktioniert es nicht. Erklärung habe ich keine.
    Kurt



  • Ich scheine blind zu sein, aber ich sehe den Unterschied zwischen deinen beiden Varianten nicht...??



  • In der Klasse einmal mit std:: und einmal ohne.

    Gruß Alex



  • der unterschied ist

    #include <iostream>
    

    fehlt in der zweiten version von team.h.
    wird aber von team.cpp includiert.
    Kurt



  • Alex_H schrieb:

    In der Klasse einmal mit std:: und einmal ohne.

    Gruß Alex

    That's it. Gibt also doch eine Erklärung.
    Kurt



  • Schade, dass bei mir beide Versionen nicht funktionieren. Ich verstehe das nicht - vielleicht liegt es an meiner Entwicklungsumgebung oder irgendwelchen Einstellungen ...



  • Guntpat schrieb:

    Schade, dass bei mir beide Versionen nicht funktionieren. Ich verstehe das nicht - vielleicht liegt es an meiner Entwicklungsumgebung oder irgendwelchen Einstellungen ...

    Bist du sicher dass du nicht den selben fehler wie ich gemacht hast ?
    team.h

    class Team  {
    public:
      Team():x(12) {}
    private:
      int x;
    friend std::ostream& operator << (std::ostream& os, const Team& );
    };
    

    mit std::ostream funktioniert die zweite version auch.
    Kurt



  • Das Aufteilen in Header und Module sollte nichts ausmachen wichtig ist das was der Compiler zu sehen kriegt also in Zuks Beispielen wären das
    team.cpp

    #include <iostream>
    class Team  {
    public:
      Team():x(12) {}
    private:
      int x;
    friend std::ostream& operator << (std::ostream& os, const Team& );
    };
    std::ostream& operator << (std::ostream& os, const Team& myTeam)
    {
       os << myTeam.x;
       return os;
    }
    

    und die zweite Version

    #include <iostream>
    class Team  {
    public:
      Team():x(12) {}
    private:
      int x;
    friend ostream& operator << (ostream& os, const Team& );
    };
    
    std::ostream& operator << (std::ostream& os, const Team& myTeam)
    {
       os << myTeam.x;
       return os;
    }
    

    Und das einzige Problem das ich sehe ist, dass du ostream benutzt ohne vorher den std Namensraum gedumpt zu haben.

    @Guntpat geht das hier:

    #include<iostream>
    using namespace std;
    class Foo{
      int a;
      friend ostream&operator<<(ostream&out, const Foo&);
    };
    ostream&operator<<(ostream&out, const Foo&foo){
      out<<foo.a;
      return out;
    }
    int main(){
      cout<<Foo();
    }
    


  • Also wie gesagt - in der gleichen Datei funktioniert es, also auch das letzte Beispiel von Dir. Und ich habe das jetzt ganz korrekt so benutzt, wie ihr das vorgeschlagen habt, aber es kommen noch immer die gleichen Kompilerfehler. Ich werde mich wohl einfach damit zufrieden geben müssen, dass ich die Operatorüberladung inline definiere...so tragisch ist das ja auch nicht, ist halt nur wegen der Sichtbarkeit des Codes bei der Schnittstelle nicht so ganz ideal!



  • Was du auch noch machen kannst (und sowieso solltest) ist sämliche Infromationen über public Getter zur Verfügung zu stellen dann brauchst du kein friend.



  • Hm, hm, welchen Compiler verwendest du ?


Anmelden zum Antworten