Aus & Eingabeoperator

In C++ ist es möglich, für eine Klasse die Ein und Ausgabeoperatoren zu überladen. Damit lassen sich dann entsprechend Daten aus einem Stream lesen oder auf ihn schreiben. Traditionell dienen hierbei Referenzen auf std::istream oder std::ostream als Parameter der Operatorüberladung. Diese ist als Memberfunktion möglich, in der Praxis ist es aber besser sie als friend Operatoren zu erstellen. Ein kurzes Beispiel:

 

struct MyIO
{
    int i;
    double d;
    std::string s;
public:
    MyIO(int i =0, double d = 1.0, const std::string& s="test"):i(i),d(d),s(s){}
    // Setter/Getter/Funktionen
    friend std::ostream& operator<<(std::ostream& o,const MyIO& obj);
    friend std::istream& operator>>(std::istream& i,MyIO& obj);
};

Die Klasse MyIO definiert 3 Membervariablen, welche nun entsprechend mit den IO Operatoren geschrieben und gelesen werden können:

 

std::ostream& operator<<(std::ostream& o,const MyIO& obj)
{
    o << obj.i << ' ';
    o << obj.d << ' ';
    //string
    o << obj.s.size() << ' ';
    o.write(obj.s.c_str(),obj.s.size());
    return o;
}

std::istream& operator>>(std::istream& i,MyIO& obj) { i >> obj.i; i >> obj.d; //string size_t size; i >> size; i.get(); // leerzeichen überlesen char* arr = new char[size+1]; i.read(arr,size); obj.s.assign(arr,size); delete[] arr; return i; }
 

Da die Funktion als friend von MyIO deklariert wurde, kann sie auf die Member direkt zugreifen, und somit diese direkt in den Stream schreiben und aus ihm lesen. Doch schon bei std::string wird es schwieriger, o << obj.s; und i >> obj.s; ist eine Möglichkeit, aber diese gibt den String nur in den Stream, und bei der Eingabe ließt es standardmäßig nur bis zum ersten Leerzeichen. Das ist nicht so geplant. Für Strings ohne Leerzeichen natürlich eine Möglichkeit der bequemen Ausgabe. Eine mögliche Alternative ist es, die Größe des Strings in den Stream zu schreiben, danach ein Leerzeichen und dann den String. Beim Auslesen wird man dann den String mit read in ein temporäres char array lesen können, welches wieder an die Membervariable weitergereicht wird.

Die Anwendung sieht dann so aus:

 

int main()
{
    MyIO a(4,5.0,"foo bar"),b;
    std::stringstream sstr;
    sstr << a;
    sstr >> b;
    std::cout << sstr.str() << std::endl << b << std::endl;
    return 0;
}
 

Die Ein und Ausgabe erfolgt hier in einen Stringstream, man könnte aber auch mit of/ifstream in Dateien schreiben oder aus ihnen lesen. Da auch std::cout den operator<< nutzt, wird die Ausgabe auf der Konsole die Gleiche sein, wie sie vorher in den Stringstream erfolgte.