Você está na página 1de 19

Aula 5:

Sobrecarga de Operadores
Parte 2

ECOP03 – Programação Orientada a Objetos


Prof. João Paulo Reus Rodrigues Leite
joaopaulo@unifei.edu.br
Sobrecarga de Operadores de Inserção e Extração de Stream

A biblioteca I/O stream provê operações de entrada e saída para


texto e tipos numéricos. Suas definições se encontram
principalmente em <istream> e <ostream>.

Um objeto do tipo ostream converte objetos de um


determinado tipo em um fluxo de caracteres (ou bytes),
enquanto um objeto do tipo istream converte um fluxo de
caracteres (bytes) em objetos de um determinado tipo.

Os fluxos (ou streams) padrão que utilizaremos são:


• cout (<<): saída padrão (geralmente para a tela)
• cin (>>): entrada padrão (geralmente através de um teclado)
Sobrecarga de Operadores de Inserção e Extração de Stream

Você pode enviar ou receber dados de qualquer tipo fundamental


utilizando o operador de extração de stream (>>) e o operador de
inserção de stream (<<).

As bibliotecas de C++ já sobrecarregam esses operadores para


processar cada um dos tipos fundamentais, incluindo até mesmo
ponteiros e strings char* no estilo C.

Você também pode sobrecarregar esses operadores para realizar


a entrada e saída para seus próprios tipos. Vejamos um exemplo:
Sobrecarga de Operadores de Inserção e Extração de Stream

Algumas coisas foram importantes na implementação. Vamos


destacá-las:

• A sobrecarga dos operadores de entrada e saída deve ser


realizada através de funções globais friend. Isso se deve ao fato
de que o primeiro operando (ou seja, o da esquerda) é sempre
o objeto que manipula o stream (cin, cout). Veja os exemplos:

cin >> p1; // repare que tanto cin quanto cout


cin >> p2 >> p3; // estão sempre do lado esquerdo
cout << p3; // da operação
Além disso,

• É importante que as funções de sobrecarga recebam, como


parâmetros, referências para istream&, ostream& e para próprio
objeto (Point&). Isso é ainda mais importante no caso do istream.
Caso seja passado o objeto por valor, as mudanças serão
realizadas em uma cópia do objeto. Portanto, utilize referências.

• Também devemos retornar uma referência para o próprio objeto


manipulador do stream ao final da função. Isso possibilita que
sejam feitas chamadas encadeadas do operador, como vemos
abaixo:

cout << “Dois pontos são ” << p1 << p2;


cin >> p3 >> p4;
Ao entrar na função sobrecarregada, os nomes dos parâmetros
tornam-se “apelidos”, ou alias, para os objetos passados para a
função. No caso do exemplo, temos:

E na chamada da operação:
Portanto, dentro da função, cin passa a ser chamado de in (ou
qualquer outro nome que deseje) e p2 passa a ser referenciado pelo
nome p. Como são referências, estes novos nomes identificam o
mesmo objeto, na mesma posição de memória.
Operadores de conversão de tipo

A maioria dos programas processa informações de muitos tipos.


Às vezes, todas as operações “permanecem dentro de um tipo”.
Por exemplo, somar um int a um int produz um int. Porém, com
certa frequência, é necessário converter dados de um tipo para
outro.

Isso pode acontecer em atribuições, cálculos, passagem de valores


para funções e retorno de valores de funções.

O compilador sabe como fazer algumas conversões entre tipos


fundamentais, e você pode utilizar operadores de conversão para
forçar conversões entre tipos fundamentais (typecast).
Operadores de conversão de tipo

Mas e os tipos definidos pelo usuário?


Os operadores de conversão de tipo proporcionam um mecanismo
para conversão de um objeto de determinada classe em um outro
tipo. A sintaxe de um operador de conversão de tipo assemelha-
se bastante à sintaxe de um operador sobrecarregado.

Por exemplo,
A::operator int() const;
A::operator OutraClasse() const;

convertem um objeto do tipo A para o tipo fundamental int e


para um objeto do tipo OutraClasse.
Veja como faríamos uma conversão do tipo Point para int:
Este tipo de conversão aconteceria tanto através da utilização
explícita do operador de conversão (int), quanto em uma
atribuição ou passagem de parâmetros. A este tipo, chamamos de
conversão implícita.

Caso o criador do tipo de dados queira evitar este tipo de


conversão implícita, restringindo a conversão apenas a
manifestações explícitas de intenção, é necessário declarar o
operador de conversão como explicit. Veja:
Operadores de comparação

Sobrecarga de operadores de comparação é muito simples uma


vez que já tenhamos entendido tudo sobre operadores
aritméticos. Veja as opções:
Da tabela anterior, podemos ver que:

• É possível sobrecarregar qualquer um dos seguintes operadores


de comparação: ==, !=, <, >, <= e >=.

• Para que os operadores funcionem de maneira semelhante aos


utilizados nos tipos fundamentais, é recomendado que o tipo de
retorno das funções seja do tipo bool.

• A sobrecarga do operador == não implica em uma sobrecarga


implícita do operador !=.

• É possível fazer a comparação entre objetos de dois tipos


diferentes T e T2 ou entre objetos de um mesmo tipo T (T2 == T)
Exemplo:
Veja como torna-se simples a utilização de operadores de
comparação utilizando tipos definidos pelo usuário. O
critério para “igualdade” e “diferença” está encapsulado
na implementação do próprio tipo. É uma comparação
completamente segura.
Agora vejamos um exemplo diferente para a aplicação de
operadores de comparação < e >.
Esta classe define que “tamanho” de uma classe de aula está
relacionado apenas ao número de estudantes, e é somente isso
que ela compara. Existe outro membro de dados, que é um
ponteiro para strings com os nomes dos alunos. Ele não contém
informação relevante para a comparação.

O mesmo tipo de lógica poderia ser aplicada nos operadores <=


e >=, para tornar o tipo mais completo.
Hands-On

Vamos implementar agora um tipo completo, com seus membros


de dados, funções membro e operadores sobrecarregados.

O tipo no qual estou interessado é “Ângulo”, para ser utilizados em


problemas de trigonometria. Veja a definição:

Euclides definiu um ângulo plano como


a inclinação entre duas linhas que se
encontram em um mesmo plano. Pode
ser medido em graus ou radianos.

Funções membro: radiano, seno, cosseno, tangente, complementar, operadores + e -,


<< e >>, e conversão de tipo para double. Atributo(s): grau.

Você também pode gostar