Liste mit Objekten ausgeben



  • Hallo,
    ich will in einer Consolenanwendung eine Liste mit Objekten der Klasse Konto.

    Jetzt meine Frage wie muss ich die Liste ausgeben lassen damit ich auch werte erhalte?

    Gibt es dort allgemeine Lösungen oder müsste ich dazu meinen Anwendungsfall genauer beschreiben?



  • Normalerweise schreibst du eine Funktion, die die Opertoren << und >> definieren, wo du dann das ein/ausgibst, was du willst.

    Danach kannst du ganz einfach von einer höheren Instanz das Objekt per << ausgeben.

    class MyClass
    {
    public:
        std::ostream & operator << ( std::ostream & out )
        {
            out << myInteger << " " << myInteger;
            return out;
        }
    private:
        int myInteger;
    };
    


  • drakon schrieb:

    class MyClass
    {
    public:
        std::ostream & operator << ( std::ostream & out )
        {
            out << myInteger << " " << myInteger;
            return out;
        }
    private:
        int myInteger;
    };
    

    Das ist ein schlechtes Beispiel. In dem Fall ist nämlich der Operator ein Member von MyClass und die Verwendung müsste andersrum geschehen als gewohnt:

    MyClass objekt;
    objekt << cout; //sieht komisch aus...
    

    Richtig wäre, einen operator<< außerhalb der Klasse zu definieren der als erstes Argument den Stream und als zweites die Klasse nimmt. Sollte die Ausgabe auf private Klassenmember zugreifen müssen, kann man den op<< entweder als friend deklarieren oder man implementiert eine Methode der Klasse, die die Aufgabe macht:

    class MyClass
    {
    /*...*/
    public:
      std::ostream& print(std::ostream& os) const
      {
        os << member1 << member2;
        return os;
      }
    };
    
    std::ostream& operator<<(std::ostream& os, MyClass const& mc)
    {
       return mc.print(os);
    }
    

    Die Entscheidung ob friend oder print-Methode ist hauptsächlich Geschmackssache. Man kann allerdings auch argumentieren, das alles was an einen Stream ausgegeben werden kann generell zugänglich sein sollte und deshalb auf jeden Fall einen Getter braucht - der op<< kann dann ganz ohne private-Zugriffe durch diese Getter implementiert werden.


  • Administrator

    Und wenn du das für das einzelne Objekt dann gemacht hast, kannst du deine Liste zum Beispiel auf folgende Art ausgeben lassen:

    #include <list>  // std::list
    #include <iostream>  // std::cout
    #include <iterator>  // std::ostream_iterator
    #include <algorithm>  // std::copy
    
    // ...
    
    // Irgendwo in einer Funktion
    
    std::list<Object> objList; // Die Liste mit den Objekten.
    
    std::ostream_iterator<Object> outIter(std::cout, "\n"); // Objekte getrennt durch neue Zeile.
    
    std::copy(objList.begin(), objList.end(), outIter); // Liste auf die Konsole "kopieren".
    

    C++-Referenz: http://www.cplusplus.com/reference/

    Grüssli



  • pumuckl schrieb:

    ...

    Ja. Sorry. Mein Fehler. War Wohl doch ein wenig zu Warm gestern. 😉 ( > 30°)



  • pumuckl schrieb:

    Die Entscheidung ob friend oder print-Methode ist hauptsächlich Geschmackssache.

    Hmm, als Geschmackssache würde ich das nicht unbedingt sehen. So eine print()-Methode bietet bekannterweise einige Vorteil bei polymorphem Verhalten.

    Und friend mag ehe keiner 🙂



  • KasF schrieb:

    Hmm, als Geschmackssache würde ich das nicht unbedingt sehen. So eine print()-Methode bietet bekannterweise einige Vorteil bei polymorphem Verhalten.

    Ich sehe hier aber auch ein Nachteil.

    Die Ausgabefunktion ist von der Ausgabe abhängig. Wenn man diese als Elementfunktion umsetzt, macht man sich in gewissen Rahmen von der Ausgabeform abhängig, sowas mag ich persönlich wiederum nicht (Schichtentrennung).

    KasF schrieb:

    Und friend mag ehe keiner 🙂

    Davon abgesehen mag ich friend an der ein oder anderen Stelle. Aber ich gebe dir in sofern Recht das friend eher die Ausnahme als die Regel sein sollte. Verwenden tue ich dies ab und an in abhängigen Klassen die nur zusammen in Erscheinung treten (Sprich eine "Komponente" darstellen), wenn ich keine sinnvolle Alternative finde ohne die Implementierung außerhalb der Komponente sichtbar zu machen.

    cu André



  • asc schrieb:

    Die Ausgabefunktion ist von der Ausgabe abhängig. Wenn man diese als Elementfunktion umsetzt, macht man sich in gewissen Rahmen von der Ausgabeform abhängig, sowas mag ich persönlich wiederum nicht (Schichtentrennung).

    Kannst du das näher erläutern ? Verstehe ich nicht ganz ...



  • KasF schrieb:

    asc schrieb:

    Die Ausgabefunktion ist von der Ausgabe abhängig. Wenn man diese als Elementfunktion umsetzt, macht man sich in gewissen Rahmen von der Ausgabeform abhängig, sowas mag ich persönlich wiederum nicht (Schichtentrennung).

    Kannst du das näher erläutern ? Verstehe ich nicht ganz ...

    Ich persönlich mag es nicht wenn Logik für eine Ausgabe in einer Klasse enthalten ist, die Ausgabe aber ggf. vom Verwendeten Umfeld abhängt. Sprich Konto wird um Ausgaberoutinen für eine Konsolenanwendung erweitert, wenn man jetzt aber die Oberfläche austauscht und z.B. eine Windowsoberfläche verwendet, müsste man entweder die Klasse wieder anpassen oder aber man hätte eine (dann) unnötige Funktion in der Klasse.

    Daher lagere ich lieber Ausgabefunktionen aus (sei es je nach Komplexität in eine eigene Klasse oder in eine freie Funktion), und ich sehe auch nicht wirklich das Problem wenn eine Ausgabe die an eine konkrete Klasse gebunden ist unter umständen als Friend deklariert wird.

    cu André



  • Ok, verstehe jetzt worauf du mit "Schichtentrennung" hinaus wollest.
    Wahrscheinlich muss man das dann je nach Anwendungsfall entscheiden, was mehr Sinn macht bzw. auch von der Erweiterbarkeit die bessere Wahl ist.


Anmelden zum Antworten