Stream-Operatoren
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 43 von 104.
Mit den Operatoren zur Einfügung in (<<) und Extraktion aus Streams (>>) kannst du deine eigenen Klassen mit std::cout und std::cin verwenden. Anders als die Operatoren, die wir bisher behandelt haben, müssen diese als Funktionen außerhalb der Klasse implementiert werden, weil der linke Operand ein Stream und nicht deine Klasse ist.
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 und ermöglichen dadurch Verkettungen wie std::cout << p1 << p2. Der Einfügeoperator übernimmt das Objekt als const-Referenz, da er die Daten nur liest, während der Extraktionsoperator eine nicht-const-Referenz übernimmt, weil er das Objekt verändert.
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
EinfachErstellen wir eine Temperature-Klasse, die durch die Überladung von Stream-Operatoren nahtlos mit std::cout und std::cin verwendet werden kann. Dies ist ein praktisches Szenario, in dem du Temperaturen in einem lesbaren Format anzeigen und sie auf natürliche Weise aus der Eingabe einlesen möchtest.
Du erstellst zwei Dateien, um deinen Code zu organisieren:
Temperature.h: Definiere eineTemperature-Klasse, die einen Temperaturwert (alsdouble) und eine Einheit (alschar, entweder'C'für Celsius oder'F'für Fahrenheit) speichert. Deine 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 übernimmt
- Getter
getValue()undgetUnit()(beide const) - Friend-Deklarationen für die Stream-Einfügeoperatoren (
<<) und Extraktionsoperatoren (>>)
Implementiere die Stream-Operatoren als Nicht-Member-Funktionen:
- Der Einfügeoperator sollte die Temperatur im Format
VALUE UNITausgeben (z. B.25.5 Coder77.9 F). Verwende eine Dezimalstelle für den Wert. - Der Extraktionsoperator sollte einen Wert und ein Einheitenzeichen aus dem Stream einlesen und sie im Temperature-Objekt speichern.
Beide Operatoren müssen eine Referenz auf den Stream zurückgeben, um Verkettungen zu ermöglichen.
main.cpp: Lies zwei Temperaturen aus der Eingabe ein. Jede Temperatur wird in einer separaten Zeile im Formatvalue unitangegeben (z. B.25.5 C).Erstelle zwei
Temperature-Objekte und verwende den Extraktionsoperator, um sie ausstd::cineinzulesen. Gib sie anschließend mit dem Einfügeoperator in diesem Format aus:Temperature 1: <temp1> Temperature 2: <temp2>Wenn die Eingabe beispielsweise wie folgt lautet:
25.5 C 98.6 FDie Ausgabe sollte wie folgt aussehen:
Temperature 1: 25.5 C Temperature 2: 98.6 F
Verwende std::fixed und std::setprecision(1) aus <iomanip>, um den Temperaturwert mit genau einer Dezimalstelle zu formatieren. Vergiss die Header-Guards in deiner Header-Datei nicht.
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 & QuelldateienNamespaces & GültigkeitsbereichEinführung in OOP mit C++Klassen vs. ObjekteDer „this“-ZeigerMethoden (Member-Funktionen)Attribute (Datenmember)Grundlagen zu Ctors & DtorsRückblick – Einfacher Taschenrechner4Klassenattribute
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen und -KlassenZusammenfassung – Bankkontoverwaltung7Vererbung
Grundlagen der VererbungZugriffsebenen bei der VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick – Mitarbeiterhierarchie2Speicherverwaltung
Stack- vs. Heap-SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Intelligente Zeiger in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsbezeichner in C++Zugriffsbezeichner im DetailInformationsverbergungStruct vs. KlasseVerschachtelte und innere KlassenWiederholung – Studierendenverwaltungssystem8Polymorphie
Polymorphie zur Compilezeit vs. LaufzeitFunktionsüberladungVirtuelle Funktionen erneut betrachtetRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIRückblick – Shape-Calculator3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorMove-KonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktor im DetailDrei-/Fünf-/Null-RegelZusammenfassung – String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladung der Operatoren [] und ()TypkonvertierungsoperatorenWiederholung – Matrix-Klasse9Templates
FunktionstemplatesKlassen-TemplatesTemplate-SpezialisierungVariadische TemplatesGrundlagen zu SFINAE und Type TraitsRückblick – Generischer ContainerÜbe selbstständig: Online-C++-Compiler