ifstream als member-Variable



  • Hoi,

    meine Projektklasse soll eine Lesemethode erhalten, die sequentiell ein File abarbeiten (nur lesen) kann. Diese soll immer wieder mal aufgerufen werden. Im Grunde wollte ich etwas machen, wie hier von "gabehabe" vorgestellt. Das Beispiel kann ich auch kompilieren. Bei meinem Code erhalte ich jedoch Fehlermeldungen.

    Der Code:

    #include <iostream>
    #include <vector>
    #include <string>
    
    namespace yamas {
        class Project {
             public:
                 unsigned int id;
                 Project();
                 Project(const std::vector<short unsigned int> &cols,
                         const std::string &ifname);
                 ~Project();
             private:
                 std::vector<short unsigned int> columns;
                 std::string fname; // file name of the input file
                 //std::ifstream inputstream;
        };
    } // end namespace yamas
    

    Ich habe alle nicht relevanten Methoden und Variablen entfernt. Das scheint so weit ok, jedoch, wenn ich die Zeile mit dem std::ifstream auskommentiere erhalte ich mit " g++ -o trunk/src/ya_project.o -c -fopenmp -O3 -Wall trunk/src/ya_project.cpp" folgende Fehlermeldung:

    /usr/include/c++/4.3/bits/ios_base.h: In copy constructor 'std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)':
    /usr/include/c++/4.3/iosfwd:52:   instantiated from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = yamas::Project]'
    /usr/include/c++/4.3/bits/stl_vector.h:690:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = yamas::Project, _Alloc = std::allocator<yamas::Project>]'
    trunk/src/ya_project.cpp:110:   instantiated from here
    /usr/include/c++/4.3/bits/ios_base.h:782: error: 'std::ios_base::ios_base(const std::ios_base&)' is private
    usw. usw.
    

    Kann mir jemand erklären wo mein Fehler liegt / wie ich ihn umschiffen kann?

    Danke,
    Christian



  • Hallo,

    Die Streamklassen sind nicht kopierbar. Wenn du also eine deiner Klasseninstanzen in einen Vektor einfügen willst, muss ja kopiert werden.
    Eine Variante wäre hier den Eingabestream als Zeiger in der Klasse zu halten (oder in einem Smartpointer). Dann mußt du den natürlich im Konstruktor erst erzeugen. Dann musst du natürlich auch Kopierkonstruktor und Zuweisungsoperator implementieren. Wenn du keinen Smartpointer verwendest brauchst du natürlich noch einen Destruktor zum Löschen.


  • Mod

    Streams sind (aus gutem Grund) nicht kopierbar. Anscheinend versuchst du aber Objekte deiner Klasse zu kopieren (packst du sie in einen vector? Dazu muss der vector nämlich Kopien erzeugen können). Der Compiler kann aber selber keinen passenden Kopierkonstruktor erzeugen.

    Lösung: Überleg dir, wie das Verhalten deiner Klasse im Falle einer Kopie aussehen soll und implementier einen entsprechenden Kopierkonstruktor.



  • Nein, die Objekte sollen nicht kopierbar sein. Aus der Compiler-Message läßt sich für mich aber auch nicht ablesen, daß ein Kopierkonstruktor, der explizite "Nichtkopierbarkeit" ausdrückt, das gewünschte Verhalten direkt umsetzen läßt. Nun, ich werde es einfach mal probieren und ansonsten auf die Zeigervariante umsteigen.

    Wie auch immer: Seltsam finde ich, dass sich das verlinkte Beispiel (nach Tippfehlerkorrektur) kompilieren ließ, es bei mir aber die Fehlermeldung gibt, und zwar vor dem Linken. Daher hatte ich halt Hoffnung, daß es einen (direkten) Weg gibt. Ist jetzt das Kompilerverhalten oder meine Hoffnung inkonsequent? 😉

    Jedenfalls vielen Dank für die Erläuterungen!

    Gruß,
    Christian



  • Dein Beispiel lässt sich solange kompilieren, wie du keinen Kopierkonstruktor aufrufst. Der wird implizit ja erst dann erzeugt wenn du ihn auch brauchst.
    push_back ruft den Kopierkonstruktor auf. Sowas musst du auch getan haben um die von dir gepostete Fehlermeldung zu bekommen.


Anmelden zum Antworten