Programação Orientada a Objetos Aula VIII Prof. Felício Bruzzi Barros Maio de 2008
Sobrecarga de operadores matriz A, B, C, D; multiplica(a,b,c); soma(a,b,d); escreve(d); matriz A, B, C, D; C=A*B; D=A+B; cout << D << endl; código mais fácil de ser compreendido; funções (operadores) mais fáceis de serem utilizadas; Sobrecarga de funções: funções com o mesmo nome, mas com diferentes parâmetros (e códigos diferentes); Sobrecarga de operadores: Operadores com o mesmo nome, mas com diferentes operandos (e códigos diferentes).
Operadores sobrecarregáveis + - * / % ^ & ~! = < > += -= *= /= %= ^= &= = << >> >>= <<= ==!= <= >= && ++ -- ->*, -> [] () new new[] delete delete[]
Operadores não-sobrecarregáveis e regras Não podem ser sobrecarregados: :: Resolução de escopo;. Seleção de membro;.* Seleção de membro através de um ponteiro para função. Regras: O operador sobrecarregado não pode alterar as regras de precedência e associatividade do C e C++; Ao menos um dos parâmetros do operador deverá ser membro de uma classe. O número de parâmetros do operador sobrecarregado depende do tipo do operador e da função: Operador unário, função membro Nenhum parâmetro Operador unário, função não membro Um parâmetro Operador binário, função membro Um parâmetro Operador binário, função não membro Dois parâmetros
Sintaxe Função com um nome especial: operator op, onde op é o operador. Sobrecarga como função membro não static: Declaração: tipo_retorno operator op (lista_de_parâmetros); Definição: tipo_retorno Nome_classe::operator op (lista_de_parâmetros) {... // código da função } Como função friend (não membro): Declaração: friend tipo_retorno operator op (lista_de_parâmetros); Definição: tipo_retorno operator op(lista_de_parâmetros) {... // código da função} Como função não membro e não friend: Declaração: tipo_retorno operator op (lista_de_parâmetros); Definição: exemplo:vetmat tipo_retorno operator op(lista_de_parâmetros) {... // código da função}
Observações Usar passagem por referência sempre que possível mas eficiente para objetos grandes (evitar o overhead ). Não se pode passar por referência uma variável local. Não se pode usar passagem por ponteiro. (não se pode sobrecarregar operadores que agem sobre ponteiros ou tipos definidos).
Conversões Criar construtor com um argumento: Declaração: tipo_1 (tipo_2); void f(tipo_1); int main() { tipo_2 A; tipo_1 B(A); // Explícita f(a); // Implícita } Declaração: explicit tipo_1 (tipo_2); void f(tipo_1); int main() { tipo_2 A; tipo_1 B(A); // Explícita f(a); // Erro } exemplo:vetmat
Operador de conversão Há casos em que o uso de um construtor para efetuar a conversão não é adequado, porque o construtor não pode especificar: Uma conversão de um tipo definido pelo usuário para um tipo básico, pois os tipos básicos não são classes; Uma conversão de um novo tipo definido pelo usuário para uma classe previamente definida (sem que se tenha a modificação da classe antiga). Nestes casos, pode-se sobrecarregar o operador de conversão, para efetuar a conversão de um objeto do tipo Classe1 para um objeto do tipo Classe2: O operador deve ser membro de Classe1; A sintaxe a ser usada em classe 1 é: operator Classe2( ); O tipo de retorno não deve ser colocado, pois ele é implicitamente igual a Classe2; Não se pode definir um operador de conversão e um construtor dedicado a efetuar a mesma conversão: isto é ilegal, pois gera ambiguidade!
Operador de conversão const float PARALELO = 1.69; class Real { double dinheiro; public : Real (double valor) { dinheiro = valor; } operator Dolar ( ); // Real em Dolar via operador operator int ( ); // Real em unsigned long friend void mostrar (unsigned long var_long) }; Real :: operator Dolar ( ) { return Dolar ((float) dinheiro/paralelo); } Real :: operator ìnt ( ) { return (int) dinheiro; } int main ( ) { Real minimo (110.00), paralelo (1.13); Dolar usa (10.50); int truncado = paralelo; Dolar minimo_dolar = minimo; truncado = (int) minimo; return 0; }
Ambigüidades class X {/*... */ X(int); X(char *); }; class Y {/*... */ Y(int); }; class Z {/*... */ Z(X);}; X f(x); Y f(y); Z g(z); f(1); // Erro: ambíguo, f(x(1)) ou f(y(1))??? f(x(1)); // OK f(y(1)); // OK g("teste"); // Erro, dois níveis de conversão definidas pelo usuário são necessários g(x("teste")); // OK, g(z(x("teste"))); Z(X) implícita g(z("teste")); // OK, g(z(x("teste"))); X("teste") implícita
Laboratório IX Cria a classe Vetor, contendo: construtor de parâmetros (passando dimensão e uma ponteiro); construtor de parâmetros (passando dimensão e um escalar para preencher o vetor); construtor de cópia; destrutor; operador de atribuição; operadores binários (+=, -=, +, -); operadores unários (+,-); função produto escalar; funções de acesso à dimensão; operadores binários para multiplicação vetor * escalar, escalar * vetor; operadores binários para divisão vetor \ escalar, escalar \ vetor; operador de fluxo <<; operadores de acesso [ ] e ( ) (leitura e modificação); Escreva um programa demonstrando a utilização desta classe Evitar o uso das funções friends.
Quarto Trabalho primeira parte Cria a classe Matriz, contendo: construtor de parâmetros (passando número de linhas, de colunas e uma ponteiro para ponteiro); construtor de parâmetros (passando número de linhas, de colunas e um escalar para preencher a matriz); construtor de cópia; construtor para conversão entre vetor e matriz (matriz coluna); destrutor; operador de atribuição; operadores binários (+=, -=, +, -); operadores unários (+,-); operador binários (*) para produto entre matrizes ; operador binários (*) para produto entre matrizes e vetor ; funções de acesso ao número de linhas e colunas; operadores binários para multiplicação matriz * escalar, escalar * matriz; operadores binários para divisão matriz \ escalar, escalar \ matriz; operador de fluxo << operadores de acesso [ ] [ ] e (, ) (leitura e modificação); Escreva um programa demonstrando a utilização desta classe Evitar o uso das funções friends.