16 Stimmen

Sicheres Überladen des Stream-Operators>>

Es gibt eine Fülle von Informationen zum Thema Überlastung operator<< nachahmen. toString() -Methode, die ein komplexes Objekt in eine Zeichenkette umwandelt. Ich bin interessiert an auch die Umsetzung der Umkehrung, operator>> um eine Zeichenkette in ein Objekt zu deserialisieren.

Durch die Inspektion der STL Quelle, das habe ich mitbekommen:

istream &operator>>(istream &, Object &);

wäre die richtige Funktionssignatur für die Deserialisierung eines Objekts vom Typ Object . Leider weiß ich nicht, wie ich das richtig umsetzen soll - insbesondere wie ich mit Fehlern umgehen soll:

  1. Wie kann man ungültige Daten im Stream anzeigen? Eine Ausnahme auslösen?
  2. In welchem Zustand sollte der Strom sein, wenn es es fehlerhafte Daten im Datenstrom?
  3. Sollten alle Flags zurückgesetzt werden, bevor die Referenz für die Operatorverkettung zurückgegeben wird?

19voto

Johannes Schaub - litb Punkte 479831
  1. Wie kann man ungültige Daten im Stream anzeigen? Eine Ausnahme auslösen?

Sie sollten die fail etwas. Wenn der Benutzer des Streams möchte, dass eine Ausnahme ausgelöst wird, kann er den Stream konfigurieren (mit istream::exceptions ), und der Stream wird entsprechend geworfen. Ich würde es so machen, dann

stream.setstate(ios_base::failbit);
  1. Welchen Zustand sollte der Stream haben, wenn er fehlerhafte Daten enthält?

Für missgebildete Daten, die nicht in das gewünschte Format passen, sollten Sie normalerweise die Option fail Bit. Bei internen stromspezifischen Fehlern wird das bad Bit verwendet wird (z. B. wenn kein Puffer an den Stream angeschlossen ist).

  1. Sollten alle Flags zurückgesetzt werden, bevor die Referenz für die Operatorverkettung zurückgegeben wird?

Ich habe noch nie von so etwas gehört.


Um zu prüfen, ob sich der Stream in einem guten Zustand befindet, können Sie die istream::sentry Klasse. Erstellen Sie ein Objekt dieser Klasse und übergeben Sie den Stream und true (um es anzuweisen, Leerzeichen nicht sofort zu überspringen). Die Sentinel wird ausgewertet zu false wenn die eof , fail o bad Bit gesetzt ist.

istream::sentry s(stream, true);
if(!s) return stream;
// now, go on extracting data...

2voto

AProgrammer Punkte 49452

Einige zusätzliche Hinweise:

  • wenn Sie den Operator>> implementieren, sollten Sie wahrscheinlich die Verwendung der bufstream und nicht andere Überladungen von operator>> verwenden;

  • Ausnahmen, die während des Vorgangs auftreten, sollten in den Failbit oder das Badbit übertragen werden (Mitglieder von streambuf können, je nach Klasse verwendet);

  • Setzen des Status kann zu einem Fehler führen; wenn Sie den Status nach dem Abfangen einer Ausnahme setzen, sollten Sie die ursprüngliche Ausnahme propagieren und nicht diejenige die durch setstate ausgelöst wurde;

  • die Breite ist ein Feld, auf das Sie achten sollten. Wenn Sie berücksichtigen, sollten Sie es auf 0 zurücksetzen. Wenn Sie mit anderen Operator>> verwenden, um grundlegende Arbeiten auszuführen, müssen Sie die Breite, die Sie übergeben aus der erhaltenen Breite berechnen;

  • die Berücksichtigung des Gebietsschemas in Erwägung ziehen.

Lange und Kreft ( Standard C++ IOStreams und Locales ) konvertieren dies sogar in mehr Details. Sie geben einen Vorlagencode für die Fehlerbehandlung vor, der etwa eine Seite.

0voto

Eugene Punkte 6941

Was die Flaggen betrifft, so weiß ich nicht, ob es irgendwo eine Norm gibt, aber es ist eine gute Idee, sie zurückzusetzen.

Boost hat dafür nette Raii-Wrapper: IO State Savers

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X