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 p2Desafio
FácilVamos 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 classeTemperatureque armazena um valor em Celsius (como umdouble) e um rótulo de unidade (como umchar, 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()egetUnit()(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 Cou77.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 formatovalue unit(por exemplo,25.5 C).Crie dois objetos
Temperatureusando o operador de extração para lê-los destd::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 FA 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ênciaconst, 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
friendpara 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 p2Experimente 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;
}
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
1Fundamentos de OOP
Arquivos ExternosBuild e Compilação em C++Arquivos Header e SourceNamespaces e EscopoIntrodução a OOP em C++Classes vs ObjetosO Ponteiro 'this'Métodos (Funções Membro)Atributos (Membros de Dados)Básico de Ctors e DtorsRecapitulação - Calculadora Simples4Propriedades de Classe
Membros de Instância vs EstáticosGetters e SettersFunções de Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRecapitulação - Gerenciador de Conta Bancária7Herança
Herança BásicaNíveis de Acesso na HerançaOrdem de Chamada de Ctor e DtorSobrescrita de MétodosFunções Virtuais e VTableHerança MúltiplaHerança VirtualRecapitulação - Hierarquia de Funcionários2Gerenciamento de Memória
Memória Stack vs HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Smart Pointers em C++RAII em C++Recapitulação - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de Acesso em C++Especificadores de Acesso em DetalhesOcultação de InformaçãoStruct vs ClassClasses Aninhadas e InternasRecapitulação - Sistema de Registros de Alunos8Polimorfismo
Polimorfismo de Compilação vs Tempo de ExecuçãoSobrecarga de FunçõesFunções Virtuais RevisitadasFunções Virtuais PurasClasses AbstratasDesign de Interfaces em C++Dynamic Casting e RTTIRecapitulação - Calculadora de Formas3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentaçãoListas de Inicialização do ConstrutorConstrutores DelegadosMergulho Profundo em DestrutoresRegra dos Três / Cinco / ZeroRecapitulação - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de StreamSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçãoTemplates de ClasseEspecialização de TemplatesTemplates VariádicosFundamentos de SFINAE e Type TraitsRecapitulação - Container Genérico