Eingabestream an eigenes Objekt binden



  • Hey ihr,

    In meinem Buch habe ich gerae etwas darüber gelernt, dass es möglich ist Iteratoren zu definieren, welche durch den Eingabestream initalisiert werden und direkt an eine eigene Klasse gebunden werden.
    Voraussetzung für diese eigene Klasse ist, dass sie den Eingabeoperator '>>' unterstützt.
    In meinem Buch fand ich folgendes Beispiel:

    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <sstream>
    #include <string>
    using namespace std;
    class Sales_item
    {
       public:
         double avg_price() const;
         bool same_isbn(const Sales_item &rhs) const
         {
            return isbn == rhs.isbn;     
         }      
       private:
         std::string isbn;
         unsigned units_sold;
         double revenue;
    };
    int main(void)
    {
        Sales_item M;
        istream_iterator<M> item(cin);   //Liesst Sales_Item Werte in cin.
    }
    

    Fehler:

    9 `M' cannot appear in a constant-expression

    Ich weiß nun wirklich nicht wie es gehen soll, dass eine Klasse den Eingabeoperator unterstüzt.
    Heißt das einfach, dass sie Elemente eines Typs enthalten muss, welche '>>' unterstützen? z.B. String?
    'item' soll im Beispiel nun eignetlich ein istream-Iterator sein, welcher auf Sales_item zeigt.

    Doch auf welche stelle in Sales_item?
    Und wie überhaupt?

    In meinem Buch ist da ne echt komische Erklärung.

    Wäre nett wenn jemand der es versteht helfen könnte 😉

    cya
    David

    PS:

    Also das :xmas1: 🙂 😉 :xmas1:



  • Du kannst einen Stream-Iterator nicht auf ein einzelnes Objekt beziehen, sondern auf einen Datentyp, also istream_iterator<Sales_item> iter(cin); .

    Und mit dieser Konstruktion erhältst du einen Stream-Iterator, der aus dem Eingabestream 'Sales_item'-Objekte herausziehen kann - jedes Mal, wenn du *iter verwendest, nutzt der deinen op>>, um ein neues Objekt von Tastatur zu holen und weiterzugeben.



  • #include <iterator>
    #include <fstream>
    #include <string>
    
    class item
    {
        std::string m_isbn;
        double m_price;
    
    public:
        double const& get_price() const { return m_price; }
        std::string const& get_isbn() const { return m_isbn; }
        bool operator==(item const& rhs) const { return m_isbn == rhs.m_isbn; }
    };
    
    class for_sale : public item
    {};
    
    class exhibit : public item
    {};
    
    class shop
    {
        std::map<item&, std::size_t> m_stock;
        double m_bilance;
    };
    

    wäre evtl. ein etwas schöneres Klassendesign für einen shop, falls du das machen willst ^^



  • Oh- du hast Recht.
    Aber wie kann ich Sales_item- Objekte 'von der Tastatur' holen, wenn Sales Item eventuell 5 Stringvariablen enthält?
    Auf welche dieser Variablen zeigt dann der Iterator?

    *Edit:

    Ohhh... ich hatte eigentlich nicht vor da noch mehr mit der Klasse zu arbeiten. War nur zum Verständnis- trotzdem danke D(Evil)*



  • Um da etwas damit zu machen, benötigst du deinen operator>>, der diese fünf Strings einliest (entweder über eine Klassenmethode oder mit friend-Zugriff):

    istream& operator>>(istream& in,Sales_item& data)
    {
      ... // lies alle Daten
      return in;
    }
    

    Verwenden tut man Stream-Iteratoren normalerweise zusammen mit STL-Algorithmen - z.B.:

    vector<Sales_item> my_data;
    copy(istream_iterator<Sales_item>(cin),istream_iterator<Sales_item>(),back_inserter(my_data));
    

Anmelden zum Antworten