Warum die Streams in C ++?

8

Wie Sie alle wissen, gibt es Bibliotheken, die Streams verwenden, z. B. iostream und fstream .

Meine Frage ist:

  • Warum Streams? Warum bleiben sie nicht bei Funktionen wie print , fgets usw. (zum Beispiel)?

Sie benötigen ihre eigenen Operatoren << und >> , aber alles, was sie tun, könnte in einfachen Funktionen wie oben implementiert werden, auch die Funktion

%Vor%

ist für mich viel lesbarer und logischer als

%Vor%

Ich denke auch, dass all diese String-Abstraktionen in C ++ alle auf (weniger effiziente) Standardfunktionsaufrufe in Binärdateien kompiliert werden.

    
oh boy 30.04.2010, 16:58
quelle

14 Antworten

24

Streams haben eine bessere Typsicherheit.

Zum Beispiel kann printf("%s", a); schrecklich falsch gehen, wenn a eine ganze Zahl ist. cout << a; hat dieses Problem nicht.

Ein weiteres Problem besteht darin, dass Streams den Objektorientierten Designmethoden besser entsprechen.

Zum Beispiel haben Sie eine einfache Anwendung, die eine Ausgabe schreibt und dann möchte, dass die Ausgabe in eine Datei statt in die Konsole geht. Bei C-Aufrufen müssen Sie alle Aufrufe von printf durch Aufrufe von fprintf ersetzen und dafür sorgen, dass FILE* auf dem Weg erhalten bleibt. Mit Streams ändern Sie einfach die konkrete Klasse des Streams, den Sie verwenden, und das ist es, der Großteil des Codes bleibt gleich:

%Vor%     
shoosh 30.04.2010, 17:04
quelle
9

Zum einen ermöglicht es Ihnen, das C ++ - Objektmodell zu nutzen, um Funktionen zu erstellen, denen es egal ist, ob sie auf Standardausgabe, eine Datei oder einen Netzwerk-Socket schreiben (wenn Sie einen Netzwerk-Socket haben, der von% stammt Code%). ZB

%Vor%

Und ähnlich für Eingabeströme.

Streams haben auch einen Vorteil, wenn es um die Eingabe und Ausgabe von Objekten geht. Was würde passieren, wenn Sie ein Objekt mit ostream einlesen wollten?

%Vor%

Selbst wenn es einen geeigneten Spezifizierer gäbe, wie würde scanf wissen, wie man die Mitglieder des Objekts ausfüllt? Bei C ++ - Streams können Sie scanf überladen und

schreiben %Vor%

Und es wird funktionieren. Ähnliches gilt für operator<< . Sie können also den Objektserialisierungscode an einer Stelle schreiben und müssen sich an keiner anderen Stelle darum kümmern.

    
Tyler McHenry 30.04.2010 17:06
quelle
7

C ++ - Streams sind typsicher. In C, wenn Sie sagen:

%Vor%

Sie erhalten keine Fehlermeldung, obwohl die Konvertierung falsch ist.

Sie scheinen sehr grundlegende C ++ Fragen zu stellen. Welches C ++ - Lehrbuch verwenden Sie, das deckt sie nicht ab?

    
anon 30.04.2010 17:02
quelle
5

printf ist nicht typsicher. Die Cout-Schnittstelle ist auch allgemeiner, was eine Menge von Dingen erlaubt, die mit der printf-Version nicht verfügbar sind. Ein gutes Beispiel ist, dass Ihr Stream-Operator für Ihre Typen, wenn Sie es richtig machen, sich auf std :: ostream als Stream bezieht, nicht auf cout. So können Sie das Ziel der Ausgabe ändern, indem Sie einfach einen anderen Stream verwenden. Um dies mit printf zu tun, müssen Sie eine ganze Menge plattformabhängiger Überschreibung der Ausgabehandles durchführen.

Ich denke auch, dass all diese String-Abstraktionen in C ++ alle auf (weniger effiziente) Standardfunktionsaufrufe in Binärdateien kompiliert werden.

Denk alles was du willst. Bis Sie Ihre Annahme tatsächlich testen, wird Ihre Meinung nicht viel Gewicht haben. Außerdem müssen Sie den Abstraktionsverlust in Betracht ziehen, der in der modernen Softwareentwicklung normalerweise viel wichtiger ist.

    
Crazy Eddie 30.04.2010 17:03
quelle
3

Abgesehen davon, dass sie typsicher und polymorph sind, sind Streams portabler. Auf einigen Systemen erfordert printf mit einem langen "% d" und auf einigen Systemen "% ld".

    
John Gordon 30.04.2010 17:29
quelle
2

Streams können miteinander verkettet werden

%Vor%     
Mex 30.04.2010 17:02
quelle
2

Ein weiterer Vorteil von Streams ist, dass sie erweiterbar sind. Mit Streams können Sie Ihre benutzerdefinierten Klassen wie eingebaute Typen arbeiten lassen:

%Vor%

Und jetzt können Sie ein foo genau wie alles andere ausdrucken:

%Vor%     
R Samuel Klatchko 30.04.2010 17:13
quelle
2

C ++ IOStreams sind lächerlich ineffizient (in den meisten Implementierungen, die ich kenne). Oft ist das kein Problem, aber wenn es ist, ist die Bibliothek im Grunde nutzlos. Es ist auch ein guter Punkt, dass die Syntax nicht intuitiv ist (und sehr, sehr ausführlich). Die Bibliothek ist komplex und unnötig schwer zu erweitern. Es ist auch nicht sehr flexibel. Im Gegensatz zu etwas wie der STL sieht IOStreams wirklich wie ein böser Traum aus. Aber es ist hier, und wir sind dran.

Der Grund, warum es hier ist, und der Grund, warum es so aussieht, ist, dass es früher entwickelt wurde, bevor C ++ eine ausgereifte Sprache war. Bevor wir jahrzehntelange Erfahrung hatten, uns zu sagen, was gutes Bibliotheksdesign ist und was nicht. Bevor jemand wirklich wusste, was die Optionen waren.

C ++ benötigte eine E / A-Bibliothek, die besser als C war. Und in einigen wichtigen Punkten sind C ++ IOStreams besser . Sie sind typsicher und erweiterbar, wie andere bereits erwähnt haben. Durch die Implementierung eines einzelnen Operators kann ich eine benutzerdefinierte Klasse ausdrucken. Das konnte mit printf nicht gemacht werden. Ich muss mir auch keine Sorgen darüber machen, Format-Spezifizierer falsch zu bekommen und Müll wegen fehlender Typsicherheit auszudrucken.

Diese Dinge benötigt um behoben zu werden. Und hey, in den frühen Tagen waren virtuelle Funktionen und das Überladen von Operatoren die Scheiße . Es sah cool aus. Natürlich wollten Bibliotheken diese Funktionen nutzen.

Die IOStreams-Bibliothek ist ein Kompromiss zwischen:

  • etwas sicherer und erweiterbarer als C's stdio.h
  • etwas effizientes
  • etwas gut gestaltet und intuitiv
  • eine Bibliothek, die tatsächlich existierte zu der Zeit, als C ++ standardisiert wurde. (Sie mussten etwas hinzufügen, also mussten sie zwischen den Kandidaten wählen, die zu der Zeit tatsächlich existierten.)

Die Bibliothek erreicht nicht all dies, und ich glaube, dass wir heute mit unserer jahrzehntelangen Erfahrung mit der Sprache eine weitaus bessere Bibliothek hätten entwerfen können. Aber Mitte der 90er Jahre, als sie nach einer I / O-Bibliothek zum Hinzufügen suchten, war dies das Beste, was sie finden konnten.

    
jalf 30.04.2010 23:28
quelle
1

Die streamähnliche Syntax mit operator<< und operator>> ermöglicht eine schöne Verkettung.

%Vor%

vs

%Vor%

Außerdem muss man beim ersten Ansatz immer über den Typ nachdenken, während beim Stream-Ansatz der Typ nicht angegeben werden muss.

    
Danvil 30.04.2010 17:03
quelle
1

In C ++ können Sie übrigens printf verwenden. Also wenn du das magst, mach weiter und benutze es.

Streams werden für viel mehr verwendet als das Schreiben von Ausgaben an die Konsole. Sie sind eine allgemeine Lösung für die Datenpufferung, die von der Bildschirmausgabe über die Verarbeitung von Dateien bis hin zu Netzwerkverkehr und Schnittstellen zu Eingabegeräten angewendet werden kann. Ihre Daten können in Streams schreiben (oder lesen), ohne sich darum zu kümmern, wohin diese Daten tatsächlich gehen.

Nehmen wir an, Sie haben ein komplexes Objekt, das Sie in die Ausgabekonsole, in eine Protokolldatei und in ein Debugging-Fenster-Popup schreiben können. Wirst du drei Funktionen schreiben, die fast genau dasselbe tun, oder wirst du eine Funktion schreiben, der du einen (y) Ausgabestrom gibst?

    
dash-tom-bang 30.04.2010 17:09
quelle
1

Eigentlich

%Vor%

scheint mir viel intuitiver als

%Vor%

Wenn Sie vorher nie als Druckvorlage erscheinen würden, würden Sie auf keinen Fall wissen, was das ist.

In beiden Fällen

%Vor%

(in mehreren Sprachen einschließlich Python :() macht viel mehr Sinn:)

    
quelle
0

Ich benutze immer noch printf, hauptsächlich weil es einfach ist, das Ausgabeformat zu steuern.

Für mich ist Typsicherheit kein Hauptvorteil, weil es leicht vom Test abgefangen werden kann, wenn man bedenkt, dass ein konsolenbasiertes Programm wesentlich einfacher zu testen ist als UI-basierte oder webbasierte Anwendungen. Wenn Sie keinen Test durchführen, können schwerwiegendere Fehler die Kompilierzeit überbrücken.

Ich stimme auch nicht mit einem anderen Grund überein, dass der Streß von Ansprüchen aufgrund der Austauschbarkeit flexibler ist. Es entspricht der Verwendung von fprintf (fout, ...) für die Austauschbarkeit. Wenn Sie die Ausgabe umleiten müssen, verwenden Sie die Pipe. Wenn Sie in einer Bibliothek sind, warum geben Sie nicht einfach einen String zurück und lassen den Anrufer entscheiden, wohin er geht?

    
Codism 30.04.2010 17:27
quelle
0

stringstream ist sicherer als snprintf / sscanf , weil es die Möglichkeit eines Pufferüberlaufs (auch "graceful failures") vollständig vermeidet.

    
Potatoswatter 30.04.2010 17:35
quelle
0

Streams arbeiten mit Templates, printf/scanf hingegen nicht.

    
UncleBens 30.04.2010 18:40
quelle

Tags und Links