Online-Referenzen haben eher kurze und vage Beschreibungen zum Zweck von std::iostream::sentry
. Wann sollte ich mich mit diesem kleinen Lebewesen beschäftigen? Wenn es nur intern verwendet werden soll, warum es öffentlich machen?Wann sollte ich mich mit std :: iostream :: sentry beschäftigen?
Antwort
Die meisten Menschen werden niemals Code schreiben, der sich mit der Erstellung von Sentry-Objekten befassen muss. Ein Sentry-Objekt wird benötigt, wenn/wenn Sie Daten aus dem Strompuffer extrahieren (oder in ihn einfügen), der dem Stream-Objekt selbst zugrunde liegt.
Solange Ihre Einführung/Entnahme Operator andere Iostream Mitglieder/Betreiber nutzt seine Arbeit zu tun, es tut nicht mit der Erstellung eines Wach Objekt zu beschäftigen haben (weil diese anderen Iostream Betreiber erstellen und Wach Objekte zerstören, wie gebraucht).
Ah, danke. Das macht für mich am meisten Sinn (besonders die zugrundeliegende Stream-Puffer-Sache).Ich war verwirrt darüber, warum die Lehrbuchbeispiele, die zeigen, wie man eigene benutzerdefinierte Stream-Operatoren schreibt, Sentry-Objekte nie erwähnt haben. –
Es wird immer dann verwendet, wenn Sie Daten mit einem Stream extrahieren oder ausgeben müssen. Das heißt, wann immer Sie eine operator>>
, den Extraktionsoperator, oder operator<<
, den Insertion-Operator machen.
Zweck ist es, die Logik zu vereinfachen: "Sind irgendwelche Fehlerbits gesetzt? Synchronisieren Sie die Puffer. Für Eingabestreams, erhalten Sie optional alle Leerzeichen aus dem Weg. Okay, fertig?"
Alle Betreiber Extraktionsstrom sollte mit beginnen:
// second parameter to true to not skip whitespace, for input that uses it
const std::istream::sentry ok(stream, icareaboutwhitespace);
if (ok)
{
// ...
}
Und alle Betreiber Einfügungsstrom sollte mit beginnen:
const std::ostream::sentry ok(stream);
if (ok)
{
// ...
}
Es ist nur ein sauberer Weg zu tun (etwas Ähnliches):
if (stream.good())
{
if (stream.tie())
stream.tie()->sync();
// the second parameter
if (!noskipwhitespace && stream.flags() & ios_base::skipws)
{
stream >> std::ws;
}
}
if (stream.good())
{
// ...
}
ostream
überspringt nur den Whitespace-Teil.
Wenn ich eine benutzerdefinierte 'operator >>' in Bezug auf andere Stream-Member-Funktionen implementieren, ist es immer noch notwendig (oder eine gute Idee), die Sentry zu verwenden? –
Was ist mit dem Insertion Operator? Ostream definiert auch Sentry. –
@GMan: Ich höre dich. Es scheint, man könnte ein ganzes Lehrbuch nur auf Iostreams schreiben. :-) –
Formatierte Eingabe für alles außer den grundlegenden Typen (int, double, usw.) macht nicht viel Sinn, und wohl nur von ihnen, wenn sie aus einem nicht interaktiven Stream wie einem Istringstream entnommen werden. Daher solltest du op nicht in erster Linie implementieren und musst dich also nicht um Sentry-Objekte kümmern.
Was ist, wenn ich möchte, dass der Überladungsoperator >> bequem formatierte Eingaben an einem Tupel von Grundtypen macht? Beispiel: struct Point {double x, double y}; Punkt Punkt; file >> point; 'Der überladene Operator >> ist in Bezug auf Operator >> für Basistypen implementiert. –
@Emile Angenommen, der Punkt ist als "x, y" formatiert, dann ist es überraschend schwierig, ihn zu implementieren >>, so dass er für Punkt richtig funktioniert UND wenn er zusammen mit allen anderen formatierten Eingabeoperatoren verwendet wird. Im Grunde sind Sie besser dran, Funktionen zu schreiben, um die spezifischen Eingaben zu parsen, die Sie erwarten, als ein verallgemeinertes Schema, das am Ende des Tages nicht mit realen Eingaben umgehen kann. –
@Neil: Ich verstehe was du sagst. Aber vielleicht wäre eine legitime Verwendung eines benutzerdefinierten Operators >> das Zurücklesen von Daten aus einer Datei, die von symmetrischen Operatoren erzeugt wird. Dies scheint die Voraussetzung für die Boost.Serialization-Bibliothek zu sein. –
Seit wann ist ein Bezeichner ein Lebewesen? Und es ist sicher nicht klein! : D – Hogan