Pearson Education Slide 1
Pearson Education Slide 2 Cap í tulo 8 Criado por Frederick H. Colclough, Colorado Technical University Sobrecarga de Operador, Amigos, e Referências
Pearson Education Slide 3 Objetivos do Estudo Fundamentos da Sobrecarga de Operador Operadores unários Como funções-membro Amigos e Conversão de Tipo Automática Funções Amigas e classes amigas Construtores para Conversão de Tipo Automática Referêcias e mais sobrecarga > Operadores: =, [ ], ++, --
Pearson Education Slide 4 Introdução à sobrecarga de operador Operadores +, -, %, ==, etc. Nada além de funções! Simplesmente chamadas com uma sintaxe diferente: x é um operador binário; x e 7 são operandos Nós apreciamos esta sintaxe como humanos Pense nela como: +(x, 7) + é o nome da função x, 7 são os argumentos A função + retorna a soma de seus argumentos
Pearson Education Slide 5 Perspectiva da Sobrecarga de Operador Operadores predefinidos Ex.: +, -, =, %, ==, /, * Funcionam para os tipos predefinidos do C++ No padrão de notação binária Nós podemos sobrecarregá-los! Para funcionar com NOSSOS tipos! Para adicionar Tipos Caractere, ou Tipos Dinheiro Apropriados às nossas necessidades Na sintaxe mais confortável para nós
Pearson Education Slide 6 Fundamentos da Sobrecarga Sobrecarregando Operadores MUITO parecido com sobrecarregar funções O próprio operador é o nome da função Exemplo de Declaração: const Dinheiro operator +(const Dinheiro& quantia1, const Dinheiro& quantia2); Sobrecarrega + para operandos de tipo Dinheiro Usa parâmetro de referência constante para aumentar a eficiência Valor retornado é do tipo Dinheiro Permite a adição de objetos Dinheiro
Pearson Education Slide 7 + Sobrecarregado Dado o exemplo anterior: Note: + sobrecarregado NÃO é uma função-membro A definição é mais complicada que a simples soma Questão da Adição de tipo Dinheiro Precisa manusear valores negativos/positivos Definições de Sobrecarga de Operador são geralmente muito simples Executa a simples adição particular ao seu tipo
Pearson Education Slide 8 Dinheiro + Definição Definição do operator + para a classe Dinheiro : Painel 8.1 páginas
Pearson Education Slide 9 ==Sobrecarregado Operador de igualdade, == Usado na comparação de objetos Dinheiro Declaração: bool operator ==(const Dinheiro& quantia1, const Dinheiro& quantia2); Retorna um tipo booleano para a igualdade Novamente, ele não é uma função-membro (Como a sobrecarga de +)
Pearson Education Slide 10 == Sobrecarregado para classe Dinheiro Definição do Operator == para a classe Dinheiro: Painel 8.1 página 210
Pearson Education Slide 11 Construtores Retornando Objetos Construtor: uma função void? Nós pensamos dessa maneira, mas não é! Uma função especial Com Propriedades Especiais PODE retornar um valor! Lembre-se do comando return na sobrecarga de + para o tipo Dinheiro: return Dinheiro(finalReais, finalCentavos); Retorna uma invocação da classe Dinheiro! Assim, o construtor na verdade retorna um objeto! Chamado de objeto anônimo
Pearson Education Slide 12 Retornando um Valor Const Considere a sobrecarga do operador + novamente: const Dinheiro operator +(const Dinheiro& quantia1, const Dinheiro& quantia2); Retorna um objeto constante? Por que? Considere o impacto de retornar um objeto não-const para ver…
Pearson Education Slide 13 Retornando um Valor não-const Considere nenhum const na declaração: Dinheiro operator +(const Dinheiro& quantia1, const Dinheiro& quantia2); Considere a expressão que chama: m1 + m2 Onde m1 e m2 são objetos Dinheiro O objeto retornado é um objeto Dinheiro Nós podemos fazer coisas com objetos! Como chamar funções-membro…
Pearson Education Slide 14 O que fazer com Objetos Não-const Podemos chamar funções-membro : Poderíamos invocar funções-membro no objeto retornado pela expressão m1+m2: (m1+m2).saida(); //Válido, correto? Sem problemas: não modifica nada (m1+m2).input(); //Válido! PROBLEMA! //Válido, mas MODIFICA! Permite a modificação do objeto anônimo ! Não podemos permitir isso aqui! Então nós definimos o objeto com const
Pearson Education Slide 15 Sobrecarregando Operadores Unários C++ tem operadores unários: Requer somente um operando ex.: - (negação) x = -y; // coloca x igual ao negativo de y Outros operadores unários: ++, -- Operadores unários também podem ser sobrecarregados
Pearson Education Slide 16 Sobrecarga de - para classe Dinheiro Declaração da função - sobrecarregada Colocada fora da definição da classe: const Dinheiro operator –(const Dinheiro& quantia); Observe: somente um argumento Uma vez que temos somente 1 operando (unário) O operador - é sobrecarregado duplamente! Para dois operandos/argumentos (binário) Para um operando/argumento (unário) Devem existir definições para ambos
Pearson Education Slide 17 Definição de - Sobrecarregado Definição da função - sobrecarregada const Dinheiro operator –(const Dinheiro& quantia) { return Dinheiro(-quantia.getReais(), -quantia.getCentavos()); } Aplica o operador unário - ao tipo predefinido A operação é conhecida para tipos predefinidos Retorna um objeto anônimo novamente
Pearson Education Slide 18 Utilização de - sobrecarregado Considere: Dinheiro quantia1(10), quantia2(6), quantia3; quantia3 = quantia1 – quantia2; Chama a sobrecarga de - binário quantia3.saida();//Apresenta $4.00 quantia3 = -quantia1; Chama a sobrecarga de - unário quantia3.saida()//Apresenta -$10.00
Pearson Education Slide 19 Sobrecarregando com funções-membros Exemplos anteriores: Funções Independentes Definidas fora da classe Podemos sobrecarregar um operador como um operador-membro Considerado função-membro como outras Quando o operador é membro da função: Somente UM parâmetro, não dois! O objeto que faz a chamada serve como o primeiro parâmetro.
Pearson Education Slide 20 Operador-membro em Ação Dinheiro custo(1, 50), imposto(0, 15), total; total = custo + imposto; Quando + é sobrecarregado como operador-membro: Variável/objeto custo é o objeto que faz a chamada E imposto é o argumento único de + Pense nisso como: total = custo.+(imposto); Declaração de + na definição da Classe: const Dinheiro operator +(const Dinheiro& quantia); Observe que existe somente um argumento
Pearson Education Slide 21 Funções const Quando construir Funções const? Funções constantes não podem alterar membros da classe Objetos constantes SÓ podem chamar funções-membros O bom estilo dita: Qualquer função-membro que NÃO vai alterar dados deveria ser feita const Use a palavra-chave const depois da declaração de função e na definição
Pearson Education Slide 22 Sobrecarregando Operadores: Qual método? Programação Orientada a Objetos Príncipios sugerem operadores membros Muitos concordam! Para manter o espírito de OOP Operadores membros são mais eficientes Não precisam chamar funções de acesso e mutantes Pelo menos uma desvantagem importante (Mais adiante neste capítulo…)
Pearson Education Slide 23 Sobrecarregando a Aplicação de Funções ( ) Operador de chamada de função ( ) Deve ser sobrecarregado como uma função-membro Permite o uso de objetos classe como função Podemos sobrecarregar para todos os números possíveis de argumentos Exemplo: UmaClasse umObjeto; umObjeto(42);
Pearson Education Slide 24 Outras sobrecargas Operadores &&, || e vírgula Versões predefinidas funcionam para o tipo bool Lembre-se: utilizam avaliação de curto-circuito Quando sobrecarregados, não utilizam mais curto-circuito Executam a avaliação completa Contrário do esperado É melhor simplesmente não sobrecarregar esses dois operadores.
Pearson Education Slide 25 Funções Amigas Funções não-membros Lembre-se: Elas acessam dados atráves das funções de acesso e mutantes Muito ineficazes (sobreposição de chamadas) Funções Amigas podem acessar diretamente membros de classes privadas Nenhuma sobreposição, mais eficiente Então: é melhor sobrecarregar operadores como amigos!
Pearson Education Slide 26 Funções Amigas Funções amigas de uma classe Não é uma função-membro Têm acesso direto aos membros privados Exatamente com funções-membros Use a palavra-chave friend na frente da declaração de função Especificada na definição de classe Mas NÃO são funções-membros!
Pearson Education Slide 27 Utilização de Funções-Amigas Sobrecarga do Operador É mais comum o uso de amigos Mais eficiente Evita a necessidade de chamar funções-membros de acesso e mutantes O operador deve ter acesso de qualquer jeito Pode-se também dar acesso total como amigo Qualquer função pode ser amiga
Pearson Education Slide 28 Pureza das Funções Amigas Amigos não são puros? O Espírito de OOP dita que todos os operadores e funções devem ser membros Muitos acreditam que amigos violam os princípios de OOP Vantajoso? Para operadores: muito! Permite a conversão de tipos automática Ainda encapsula: amigos estão na definição da classe Melhora a eficiência
Pearson Education Slide 29 Classes Amigas Classes completas podem ser amigas da mesma forma que uma função pode ser amiga de uma classe. Exemplo: classe F é amiga da classe C Todas as funções-membros da classe F são amigas de C A recíproca NÃO é verdadeira Amizade é dada, não tomada Sintaxe: friend class F Vai dentro da definição de classe autorizando a classe
Pearson Education Slide 30 Referências Referências definidas: Nome de uma posição de armazenamento Semelhante a um ponteiro Exemplo de referência independente: int roberto; int& beto = roberto; beto uma referência à posição de armazenamento de roberto Mudanças feitas em beto afetarão roberto Confuso?
Pearson Education Slide 31 Utilização de Referências Aparentemente Perigoso Útil em vários casos: Chamada-por-referência Muitas vezes usadas para implementar esse mecanismo Retornar uma referência Permitirá que se sobrecarreguem certos operadores de um modo mais natural Pense no retorno como um alias(apelido) para a variável
Pearson Education Slide 32 Retornando Referências Sintaxe: double& amostraFuncao(double& variavel); double& and double são diferentes Deve estar na declaração e na definição da função O item retornado deve ter uma referência Como uma variável daquele tipo Não pode ser uma expressão como x+5 Não há local na memória para isso
Pearson Education Slide 33 Retornando Referência na Definição Exemplo de Definição de Função double& amostraFuncao(double& variavel); { return variavel; } Banal, exemplo inútil Mostra apenas o conceito Uso Principal: Certos operadores sobrecarregados
Pearson Education Slide 34 Sobrecarregando >> e << Habilitam a entrada e saída de seus objetos Parecidos com a sobrecarga de outros operadores Novas sutilezas Melhora a legibilidade Como fazem outras sobrecargas de operadores Habilita: cout > meuObjeto; Em vez de necessitar: meuObjeto.saida(); …
Pearson Education Slide 35 Sobrecarregando >> Operador de inserção, << Usado com cout Um Operador binário Exemplo: cout << Olá; O Operador é: << 1 o operando é: Objeto predefinido cout Da biblioteca iostream 2 o operando é: A Literal Olá
Pearson Education Slide 36 Sobrecarregando >> Operandos de >> Objeto cout, do tipo classe ostream Nosso tipo classe Lembre-se da classe Dinheiro Foi usada a função-membro saida() Seria melhor se nós pudéssemos usar o operador >>: Dinheiro quantia(100); cout << "Eu tenho "; quantia.saida( ); cout << " em minha carteira.\n";
Pearson Education Slide 37 Valor de Retorno de >> sobrecarregado Dinheiro quantia(100); cout << quantia; << deveria retornar algum valor Para permitir cascateamento: cout << Eu tenho << quantia; (cout << Eu tenho ) << quantia; Os dois são equivalentes O que retorna? Objeto cout! Retorna seu primeiro argumento, ostream
Pearson Education Slide 38 Exemplo de >> Sobrecarregado Painel 8.5 página 227
Pearson Education Slide 39 Exemplo de >> Sobrecarregado (cont) Painel 8.5 página 228
Pearson Education Slide 40 Exemplo de >> Sobrecarregado (cont) Painel 8.5 página 229
Pearson Education Slide 41 Operador de Atribuição, = Deve ser sobrecarregado como operador-membro Automaticamente sobrecarregado Operador de atribuição padrão: Variáveis-membro de um objeto correspondendo à variáveis-membro de outro Padrão OK para classes simples Mas com ponteiros Precisamos escrever o nosso!
Pearson Education Slide 42 Incremento e Decremento Cada operador tem duas versões Notação de prefixo: ++x; Notação de sufixo: x++; Precisamos distingüir quando sobrecarregarmos Método de sobrecarga padrão Prefixo Acrescentar 2 o parâmetro de tipo int sufixo Como um marcador para o compilador! Especifica que é permitido o sufixo
Pearson Education Slide 43 Sobrecarga do Operador de Vetor, [ ] Podemos sobrecarregar [ ] para uma classe Para serem utilizados com objetos da classe Operador deve retornar uma referência! Operador [ ] deve ser uma função-membro!
Pearson Education Slide 44 Sumário 1 Os operadores de C++ podem ser sobrecarregados Para trabalhar com os objetos de suas classes Operadores são como funções Funções amigas têm acesso direto a membros privados Operadores podem ser sobrecarregados como funções-membros O 1 o operando é o objeto que faz a chamada
Pearson Education Slide 45 Sumário 2 Funções amigas melhoram somente a eficiência Não necessárias se existem funções de acesso e mutantes suficientes Referem-se à variáveis com um apelido (alias) Pode-se sobrecarregar > Tipo de retorno é uma referência