Menu
Coddy logo textTech

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 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 nimmt das Objekt als const-Referenz entgegen, da er nur Daten liest, während der Extraktionsoperator eine Nicht-const-Referenz entgegennimmt, da 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 einlesen
challenge icon

Aufgabe

Einfach

Lassen 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 eine Temperature-Klasse, die einen Wert in Celsius (als double) und ein Einheiten-Label (als char, 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() und getUnit() (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 UNIT ausgeben (z. B. 25.5 C oder 77.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 Format value unit angegeben (z. B. 25.5 C).

    Erstellen Sie zwei Temperature-Objekte und verwenden Sie den Extraktionsoperator, um sie von std::cin zu 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 F

    Sollte 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.

Spickzettel

Stream-Einfüge- (<<) und Extraktions-Operatoren (>>) ermöglichen es benutzerdefinierten Klassen, mit std::cout und std::cin zu arbeiten. Diese Operatoren müssen als Nicht-Elementfunktionen implementiert werden, da der linke Operand ein Stream-Objekt ist und nicht Ihre Klasse.

Grundlegende Syntax

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;
}

Wichtige Punkte

  • Beide Operatoren geben eine Referenz auf den Stream zurück, um eine Verkettung zu ermöglichen (z. B. std::cout << p1 << p2)
  • Der Einfüge-Operator (<<) nimmt das Objekt als const-Referenz entgegen, da er Daten nur liest
  • Der Extraktions-Operator (>>) nimmt eine Nicht-const-Referenz entgegen, da er das Objekt modifiziert
  • Verwenden Sie friend-Deklarationen, um diesen Nicht-Elementfunktionen den Zugriff auf private Member zu ermöglichen

Anwendungsbeispiel

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 einlesen

Probier es selbst

#include <iostream>
#include "Temperature.h"

int main() {
    // TODO: Erstelle zwei Temperature-Objekte
    
    // TODO: Verwende den Extraktionsoperator (>>), um zwei Temperaturen von std::cin einzulesen
    
    // TODO: Gib die Temperaturen mit dem Einfügeoperator (<<) aus
    // Format:
    // Temperature 1: <temp1>
    // Temperature 2: <temp2>
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung