Menu
Coddy logo textTech

Операторы потоков

Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy — урок 43 из 104.

Операторы вставки в поток (<<) и извлечения из потока (>>) позволяют использовать ваши пользовательские классы с std::cout и std::cin. В отличие от операторов, которые мы рассматривали до сих пор, они должны быть реализованы как функции, не являющиеся членами класса, поскольку левый операнд является потоком, а не вашим классом.

class Point {
    int x, y;
    
public:
    Point(int x, int y) : x(x), y(y) {}
    
    // Объявляем как дружественную функцию для доступа к приватным членам
    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;
}

Оба оператора возвращают ссылку на поток, что позволяет выстраивать цепочки вызовов, например std::cout << p1 << p2. Оператор вставки принимает объект по const ссылке, так как он только считывает данные, в то время как оператор извлечения принимает неконстантную ссылку, так как он изменяет объект.

Теперь вы можете использовать Point естественным образом с потоками:

Point p(3, 4);
std::cout << "Location: " << p << std::endl;    // Вывод: Location: (3, 4)

Point p2(0, 0);
std::cin >> p2;    // Считать два целых числа в p2
challenge icon

Задание

Легко

Давайте создадим класс Temperature, который можно будет легко использовать с std::cout и std::cin благодаря перегрузке операторов потока. Это практический сценарий, когда вы хотите отображать температуру в читаемом формате и естественным образом считывать её из входных данных.

Для организации кода вы создадите два файла:

  • Temperature.h: Определите класс Temperature, который хранит значение температуры (как double) и обозначение единицы измерения (как char, либо 'C' для Цельсия, либо 'F' для Фаренгейта). Ваш класс должен содержать:
    • Приватные члены для значения температуры и единицы измерения
    • Конструктор по умолчанию, который инициализирует значение 0.0 градусов Цельсия
    • Параметризованный конструктор, принимающий значение и единицу измерения
    • Геттеры getValue() и getUnit() (оба const)
    • Дружественные объявления (friend) для операторов вставки в поток (<<) и извлечения из потока (>>)

    Реализуйте операторы потока как функции, не являющиеся членами класса:

    • Оператор вставки должен выводить температуру в формате VALUE UNIT (например, 25.5 C или 77.9 F). Используйте один десятичный знак для значения.
    • Оператор извлечения должен считывать значение и символ единицы измерения из потока и сохранять их в объекте Temperature.

    Оба оператора должны возвращать ссылку на поток для обеспечения возможности цепочного вызова.

  • main.cpp: Считайте две температуры из входных данных. Каждая температура указывается в отдельной строке в формате value unit (например, 25.5 C).

    Создайте два объекта Temperature, используя оператор извлечения для их чтения из std::cin. Затем выведите их с помощью оператора вставки в следующем формате:

    Temperature 1: <temp1>
    Temperature 2: <temp2>

    Например, если на входе:

    25.5 C
    98.6 F

    Вывод должен быть таким:

    Temperature 1: 25.5 C
    Temperature 2: 98.6 F

Используйте std::fixed и std::setprecision(1) из библиотеки <iomanip>, чтобы отформатировать значение температуры ровно с одним десятичным знаком. Не забудьте про include guards (защиту от повторного включения) в заголовочном файле.

Попробуйте сами

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

int main() {
    // TODO: Создайте два объекта Temperature
    
    // TODO: Используйте оператор извлечения (>>) для чтения двух температур из std::cin
    
    // TODO: Выведите температуры, используя оператор вставки (<<)
    // Формат:
    // Temperature 1: <temp1>
    // Temperature 2: <temp2>
    
    return 0;
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование