Stream-Operatoren
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 43 von 104.
Die Stream-Einfüge- (<<) und -Extraktions-Operatoren (>>) ermöglichen es Ihnen, Ihre benutzerdefinierten Klassen mit std::cout und std::cin zu verwenden. Im Gegensatz zu den Operatoren, die wir bisher behandelt haben, müssen diese als Nicht-Elementfunktionen (non-member functions) implementiert werden, da der linke Operand ein Stream ist und nicht Ihre Klasse.
class Point {
int x, y;
public:
Point(int x, int y) : x(x), y(y) {}
// Als Friend deklarieren, um auf private Member zuzugreifen
friend std::ostream& operator<<(std::ostream& os, const Point& p);
friend std::istream& operator>>(std::istream& is, Point& p);
};
std::ostream& operator<<(std::ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
std::istream& operator>>(std::istream& is, Point& p) {
is >> p.x >> p.y;
return is;
}Beide Operatoren geben eine Referenz auf den Stream zurück, was eine Verkettung wie std::cout << p1 << p2 ermöglicht. Der Einfügeoperator übernimmt das Objekt als const-Referenz, da er nur Daten liest, während die Extraktion eine Nicht-const-Referenz übernimmt, da sie das Objekt modifiziert.
Nun können Sie Point natürlich mit Streams verwenden:
Point p(3, 4);
std::cout << "Location: " << p << std::endl; // Ausgabe: Location: (3, 4)
Point p2(0, 0);
std::cin >> p2; // Zwei Ganzzahlen in p2 einlesenAufgabe
EinfachLassen Sie uns eine Temperature-Klasse erstellen, die nahtlos mit std::cout und std::cin durch Überladen von Stream-Operatoren verwendet werden kann. Dies ist ein praktisches Szenario, in dem Sie Temperaturen in einem lesbaren Format anzeigen und sie natürlich aus der Eingabe lesen möchten.
Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:
Temperature.h: Definieren Sie eineTemperature-Klasse, die einen Temperaturwert (alsdouble) und ein Einheiten-Label (alschar, entweder'C'für Celsius oder'F'für Fahrenheit) speichert. Ihre Klasse sollte Folgendes enthalten:- Private Member für den Temperaturwert und die Einheit
- Einen Standardkonstruktor, der auf 0.0 Celsius initialisiert
- Einen parametrisierten Konstruktor, der einen Wert und eine Einheit entgegennimmt
- Getter
getValue()undgetUnit()(beide const) - Friend-Deklarationen für die Stream-Einfügung (
<<) und Stream-Extraktion (>>) Operatoren
Implementieren Sie die Stream-Operatoren als Nicht-Member-Funktionen:
- Der Einfügeoperator sollte die Temperatur im Format
VALUE UNITausgeben (z. B.25.5 Coder77.9 F). Verwenden Sie eine Dezimalstelle für den Wert. - Der Extraktionsoperator sollte einen Wert und ein Einheitenzeichen aus dem Stream lesen und diese im Temperature-Objekt speichern.
Beide Operatoren müssen eine Referenz auf den Stream zurückgeben, um Verkettung zu ermöglichen.
main.cpp: Lesen Sie zwei Temperaturen aus der Eingabe. Jede Temperatur wird in einer separaten Zeile im Formatvalue unitangegeben (z. B.25.5 C).Erstellen Sie zwei
Temperature-Objekte und verwenden Sie den Extraktionsoperator, um sie vonstd::cinzu lesen. Geben Sie sie dann mit dem Einfügeoperator in diesem Format aus:Temperature 1: <temp1> Temperature 2: <temp2>Wenn die Eingabe beispielsweise wie folgt aussieht:
25.5 C 98.6 FSollte die Ausgabe wie folgt lauten:
Temperature 1: 25.5 C Temperature 2: 98.6 F
Verwenden Sie std::fixed und std::setprecision(1) aus <iomanip>, um den Temperaturwert mit genau einer Dezimalstelle zu formatieren. Vergessen Sie nicht die Header-Guards in Ihrer Header-Datei.
Probier es selbst
#include <iostream>
#include "Temperature.h"
int main() {
// TODO: Erstellen Sie zwei Temperature-Objekte
// TODO: Verwenden Sie den Extraktionsoperator (>>), um zwei Temperaturen von std::cin einzulesen
// TODO: Geben Sie die Temperaturen mit dem Einfügeoperator (<<) aus
// Format:
// Temperature 1: <temp1>
// Temperature 2: <temp2>
return 0;
}Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamensräume & GültigkeitsbereicheEinführung in OOP in C++Klassen vs. ObjekteDer 'this'-PointerMethoden (Elementfunktionen)Attribute (Datenelemente)Grundlagen zu Ctors & DtorsRückblick - Einfacher Taschenrechner4Klasseneigenschaften
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen & KlassenZusammenfassung - Bankkonto-Manager7Vererbung
Grundlagen der VererbungZugriffsstufen bei VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick - Mitarbeiter-Hierarchie2Speicherverwaltung
Stack vs. Heap SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Smart Pointers in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsspezifizierer in C++Zugriffsspezifizierer im DetailInformation HidingStruct vs. ClassVerschachtelte & innere KlassenRückblick - Studentenverwaltungssystem8Polymorphie
Kompilierzeit- vs. Laufzeit-PolymorphieFunktionsüberladungVirtuelle Funktionen – WiederholungRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIZusammenfassung – Formen-Rechner3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorVerschiebekonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktoren im DetailRule of Three / Five / ZeroZusammenfassung - String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladen der [] und () OperatorenTypumwandlungsoperatorenRückblick - Matrix-Klasse9Templates
FunktionstemplatesKlassentemplatesTemplate-SpezialisierungVariadische TemplatesSFINAE & Type Traits GrundlagenRückblick - Generische Container