Menu
Coddy logo textTech

Operadores de Stream

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 43 de 104.

Os operadores de inserção de fluxo (<<) e extração (>>) permitem que você use suas classes personalizadas com std::cout e std::cin. Ao contrário dos operadores que cobrimos até agora, estes devem ser implementados como funções não-membro porque o operando da esquerda é um fluxo, não a sua classe.

class Point {
    int x, y;
    
public:
    Point(int x, int y) : x(x), y(y) {}
    
    // Declarar como friend para acessar membros privados
    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;
}

Ambos os operadores retornam uma referência para o stream, permitindo o encadeamento como std::cout << p1 << p2. O operador de inserção recebe o objeto por referência const, já que ele apenas lê os dados, enquanto a extração recebe uma referência não-const porque ela modifica o objeto.

Agora você pode usar Point naturalmente com streams:

Point p(3, 4);
std::cout << "Location: " << p << std::endl;    // Saída: Location: (3, 4)

Point p2(0, 0);
std::cin >> p2;    // Lê dois inteiros para p2
challenge icon

Desafio

Fácil

Vamos construir uma classe Temperature que possa ser usada perfeitamente com std::cout e std::cin através da sobrecarga de operadores de fluxo. Este é um cenário prático onde você deseja exibir temperaturas em um formato legível e lê-las da entrada de forma natural.

Você criará dois arquivos para organizar seu código:

  • Temperature.h: Defina uma classe Temperature que armazena um valor em Celsius (como um double) e um rótulo de unidade (como um char, sendo 'C' para Celsius ou 'F' para Fahrenheit). Sua classe deve ter:
    • Membros privados para o valor da temperatura e a unidade
    • Um construtor padrão que inicializa para 0.0 Celsius
    • Um construtor parametrizado que recebe um valor e uma unidade
    • Getters getValue() e getUnit() (ambos const)
    • Declarações friend para os operadores de inserção de fluxo (<<) e extração (>>)

    Implemente os operadores de fluxo como funções não-membro:

    • O operador de inserção deve exibir a temperatura no formato VALUE UNIT (por exemplo, 25.5 C ou 77.9 F). Use uma casa decimal para o valor.
    • O operador de extração deve ler um valor e um caractere de unidade do fluxo e armazená-los no objeto Temperature.

    Ambos os operadores devem retornar uma referência ao fluxo para permitir o encadeamento.

  • main.cpp: Leia duas temperaturas da entrada. Cada temperatura é fornecida em uma linha separada no formato value unit (por exemplo, 25.5 C).

    Crie dois objetos Temperature usando o operador de extração para lê-los de std::cin. Em seguida, exiba-os usando o operador de inserção neste formato:

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

    Por exemplo, se a entrada for:

    25.5 C
    98.6 F

    A saída deve ser:

    Temperature 1: 25.5 C
    Temperature 2: 98.6 F

Use std::fixed e std::setprecision(1) de <iomanip> para formatar o valor da temperatura com exatamente uma casa decimal. Não se esqueça dos header guards em seu arquivo de cabeçalho.

Folha de consulta

Os operadores de inserção de fluxo (<<) e extração (>>) permitem que classes personalizadas funcionem com std::cout e std::cin. Esses operadores devem ser implementados como funções não-membro porque o operando da esquerda é um objeto de fluxo, não a sua classe.

Sintaxe Básica

class Point {
    int x, y;
    
public:
    Point(int x, int y) : x(x), y(y) {}
    
    // Declarar como friend para acessar membros privados
    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;
}

Pontos Chave

  • Ambos os operadores retornam uma referência para o fluxo para permitir o encadeamento (ex: std::cout << p1 << p2)
  • O operador de inserção (<<) recebe o objeto por referência const, já que ele apenas lê os dados
  • O operador de extração (>>) recebe uma referência não-const porque ele modifica o objeto
  • Use declarações friend para permitir que essas funções não-membro acessem membros privados

Exemplo de Uso

Point p(3, 4);
std::cout << "Location: " << p << std::endl;    // Saída: Location: (3, 4)

Point p2(0, 0);
std::cin >> p2;    // Lê dois inteiros para p2

Experimente você mesmo

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

int main() {
    // TODO: Crie dois objetos Temperature
    
    // TODO: Use o operador de extração (>>) para ler duas temperaturas de std::cin
    
    // TODO: Exiba as temperaturas usando o operador de inserção (<<)
    // Formato:
    // Temperatura 1: <temp1>
    // Temperatura 2: <temp2>
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos