Sobrecarga do operador

Da Wikipédia, a enciclopédia livre
Ir para navegação Pular para pesquisar

Em programação de computador , a sobrecarga de operador , às vezes chamada de polimorfismo ad hoc de operador , é um caso específico de polimorfismo , em que diferentes operadores têm implementações diferentes dependendo de seus argumentos. A sobrecarga do operador é geralmente definida por uma linguagem de programação , um programador ou ambos.

Justificativa

A sobrecarga de operador é um açúcar sintático e é usado porque permite a programação usando notação mais próxima do domínio de destino [1] e permite aos tipos definidos pelo usuário um nível semelhante de suporte sintático aos tipos construídos em uma linguagem. É comum, por exemplo, na computação científica, onde permite que representações computacionais de objetos matemáticos sejam manipuladas com a mesma sintaxe do papel.

A sobrecarga do operador não altera o poder expressivo de uma linguagem (com funções), pois pode ser emulada por meio de chamadas de função. Por exemplo, considere as variáveis a, be cde algum tipo definido pelo usuário, tais como matrizes :

a + b * c

Em uma linguagem que suporta sobrecarga de operador e com a suposição usual de que o operador '*' tem precedência mais alta do que o operador '+', esta é uma maneira concisa de escrever:

Add(a, Multiply(b, c))

No entanto, a sintaxe anterior reflete o uso matemático comum.

Exemplos

Nesse caso, o operador de adição está sobrecarregado para permitir a adição em um tipo definido pelo usuário Timeem C ++ :

 Operador de tempo + ( const  Time &  lhs ,  const  Time &  rhs )  { 
  Time  temp  =  lhs ; 
  temp . segundos  + =  rhs . segundos ; 
  temp . minutos  + =  temp . segundos  /  60 ; 
  temp . segundos  % =  60 ; 
  temp . minutos  + =  rhs . minutos ; 
  temp. horas  + =  temp . minutos  /  60 ; 
  temp . minutos  % =  60 ; 
  temp . horas  + =  rhs . horas ; 
  return  temp ; 
}

A adição é uma operação binária , o que significa que possui dois operandos . Em C ++, os argumentos passados ​​são os operandos e o tempobjeto é o valor retornado.

A operação também pode ser definida como um método de classe, substituindo lhspelo thisargumento oculto ; No entanto, isso força o operando esquerdo a ser do tipo Time:

// O "const" logo antes da chave de abertura significa que | this | não é modificado. 
Time  Time :: operator + ( const  Time &  rhs )  const  { 
  Time  temp  =  * this ;   // | isso | não deve ser modificado, então faça uma cópia. 
  temp . segundos  + =  rhs . segundos ; 
  temp . minutos  + =  temp . segundos  /  60 ; 
  temp . segundos  % =  60 ;
  temp . minutos  + =  rhs . minutos ; 
  temp . horas  + =  temp . minutos  /  60 ; 
  temp . minutos  % =  60 ; 
  temp . horas  + =  rhs . horas ; 
  return  temp ; 
}

Observe que um operador unário definido como um método de classe não receberia nenhum argumento aparente (ele só funciona this):

bool  Time :: operator ! ()  const  { 
  horas de retorno  == 0 && minutos == 0 && segundos == 0 ; }          

O operador menor que (<) costuma ser sobrecarregado para classificar uma estrutura ou classe:

class  Pair  { 
 public : 
  bool  operator < ( const  Pair &  p )  const  { 
    if  ( x_  ==  p . x_ )  { 
      return  y_  <  p . y_ ; 
    } 
    return  x_  <  p . x_ ; 
  }

 privado : 
  int  x_ ; 
  int  y_ ; 
};

Como nos exemplos anteriores, no último exemplo, a sobrecarga do operador é feita dentro da classe. Em C ++, após sobrecarregar o operador menor que (<), as funções de classificação padrão podem ser usadas para classificar algumas classes.

Críticas

A sobrecarga de operadores tem sido freqüentemente criticada [2] porque permite aos programadores reatribuir a semântica dos operadores dependendo dos tipos de seus operandos. Por exemplo, o uso do <<operador em C ++ desloca os bits na variável deixados por bits se e forem de um tipo inteiro, mas se for um fluxo de saída, o código acima tentará escrever um no fluxo. Como a sobrecarga de operador permite que o programador original altere a semântica usual de um operador e pegue quaisquer programadores subsequentes de surpresa, é considerada uma boa prática usar a sobrecarga de operador com cuidado (os criadores do Java decidiram não usar esse recurso, [3]a << bababab embora não necessariamente por esse motivo).

Outro problema mais sutil com os operadores é que certas regras da matemática podem ser erroneamente esperadas ou assumidas não intencionalmente. Por exemplo, a comutatividade de + (ou seja, que a + b == b + a) nem sempre se aplica; um exemplo disso ocorre quando os operandos são strings, uma vez que + é comumente sobrecarregado para realizar uma concatenação de strings (ou seja , "bird" + "song"rendimentos "birdsong", enquanto "song" + "bird"rendimentos "songbird"). Um contador típico [ carece de fontes ] para este argumento vem diretamente da matemática: Embora + seja comutativo em inteiros (e mais geralmente qualquer número complexo), não é comutativo para outros "tipos" de variáveis. Na prática, + nem sempre é associativo, por exemplo, com valores de ponto flutuante devido a erros de arredondamento. Outro exemplo: em matemática, a multiplicação é comutativa para números reais e complexos, mas não é comutativa na multiplicação de matrizes .

Catálogo

Uma classificação de algumas linguagens de programação comuns é feita de acordo com se seus operadores são sobrecarregados pelo programador e se os operadores estão limitados a um conjunto predefinido.

Operadores Não sobrecarregável Sobrecarregável
Novo definível [4]
Conjunto limitado

Cronologia da sobrecarga de operadores

1960

A especificação ALGOL 68 permitia sobrecarga do operador. [43]

Extraia da especificação de linguagem ALGOL 68 (página 177) onde os operadores sobrecarregados ¬, =, ≠ e abs são definidos:

10.2.2. Operações em Operandos Booleanos
a) op ∨ = ( bool a, b) bool :( a | true | b);
b) op ∧ = ( bool a, b) bool : (a | b | falso );
c) op ¬ = ( bool a) bool : (a | falso | verdadeiro );
d) op = = ( bool a, b) bool :( a∧b) ∨ (¬b∧¬a);
e) op ≠ = ( bool a, b) bool : ¬ (a = b);
f) op  abs = ( bool a) int : (a | 1 | 0);

Observe que nenhuma declaração especial é necessária para sobrecarregar um operador, e o programador está livre para criar novos operadores.

1980

Ada suporta a sobrecarga de operadores desde o seu início, com a publicação do padrão de linguagem Ada 83. No entanto, os designers da linguagem optaram por impedir a definição de novos operadores. Apenas os operadores existentes na linguagem podem ser sobrecarregados, definindo novas funções com identificadores como "+", "*", "&" etc. As revisões subsequentes da linguagem (em 1995 e 2005) mantêm a restrição à sobrecarga dos operadores existentes .

Em C ++ , a sobrecarga de operador é mais refinada do que em ALGOL 68 . [44]

Década de 1990

Os designers de linguagem Java da Sun Microsystems optaram por omitir a sobrecarga. [45] [46] [47]

Ruby permite a sobrecarga de operador como açúcar sintático para chamadas de método simples.

Lua permite a sobrecarga de operadores como açúcar sintático para chamadas de método com o recurso adicional de que, se o primeiro operando não definir esse operador, o método para o segundo operando será usado.

2000

A Microsoft adicionou a sobrecarga de operador ao C # em 2001 e ao Visual Basic .NET em 2003.

Scala trata todos os operadores como métodos e, portanto, permite a sobrecarga do operador por proxy.

No Raku , a definição de todos os operadores é delegada a funções lexicais e, portanto, usando as definições de função, os operadores podem ser sobrecarregados ou novos operadores adicionados. Por exemplo, a função definida na fonte Rakudo para incrementar um objeto Date com "+" é:

multi  infixo: <+> ( Data: D  $ d , Int: D  $ x ) {
     Data . new-from-daycount ( $ d . daycount + $ x )
}

Como "multi" foi usado, a função é adicionada à lista de candidatos de multidispatch , e "+" só é sobrecarregado para o caso em que as restrições de tipo na assinatura da função são atendidas. Embora a capacidade de sobrecarga inclua + , * , > = , o postfix e o termo i e assim por diante, também permite sobrecarregar vários operadores de chave: " [ x, y ] ", "x [ y ] ", "x { y } "e" x ( y ) ".

O Kotlin oferece suporte à sobrecarga de operador desde sua criação.

Veja também

Referências

  1. ^ Stroustrup, Bjarne . "Sobrecarga do operador" . C ++ FAQ . Arquivado do original em 14 de agosto de 2011 . Página visitada em 27 de agosto de 2020 .
  2. ^ Fisher, Charles N. (2008). "Problemas de sobrecarga" (PDF) . Universidade de Wisconsin-Madison .
  3. ^ "Não há mais sobrecarga do operador" . O ambiente de linguagem Java . Oracle Corporation .
  4. ^ Operadores completamente novos podem ser adicionados.
  5. ^ Funções binárias com um nome simbólico podem ser chamadas de infixo.
  6. ^ "Predicado op / 3" .
  7. ^ Hunt, John (6 de dezembro de 2012). Smalltalk e orientação a objetos: uma introdução . Springer Science & Business Media. ISBN 978-1-4471-0961-7.
  8. ^ "Bertrand Meyer: Mecanismos básicos da linguagem Eiffel" . se.ethz.ch . Página visitada em 7 de abril de 2021 .
  9. ^ www.mathcs.emory.edu http://www.mathcs.emory.edu/~cheung/Courses/561/Syllabus/6-Fortran/operators.html . Página visitada em 7 de abril de 2021 . Ausente ou vazio |title=( ajuda )
  10. ^ Introduzido em Fortran 90.
  11. ^ "3. Referência da linguagem - documentação do Futhark 0.19.0" . futhark.readthedocs.io . Página visitada em 10 de outubro de 2020 .
  12. ^ Smith, Chris (9 de outubro de 2012). Programação F # 3.0: um guia abrangente para escrever código simples para resolver problemas complexos . O'Reilly Media, Inc. ISBN 978-1-4493-2604-3.
  13. ^ Digite classes em vez de sobrecarregar.
  14. ^ "guia io" . iolanguage.org . Página visitada em 7 de abril de 2021 .
  15. ^ "Operadores - R em poucas palavras, 2ª edição [livro]" . www.oreilly.com . Página visitada em 7 de abril de 2021 .
  16. ^ "Criando operadores" .
  17. ^ "Operadores" . Tour de Scala .
  18. ^ "Manual Seed7: Definição de sintaxe estruturada" . seed7.sourceforge.net . Página visitada em 29 de setembro de 2020 .
  19. ^ "Swift: Operadores avançados" .
  20. ^ "Por que Go não suporta sobrecarga de métodos e operadores?" . Retirado em 4 de setembro de 2011 .
  21. ^ "Introdução" . freepascal.org . Retirado em 30 de setembro de 2020 .
  22. ^ "Sobrecargas de operador" . Retirado em 28 de setembro de 2018 .
  23. ^ "6.6 Sobrecarga de operadores" . Manual de referência da Ada anotado .
  24. ^ Drayton, Peter; Albahari, Ben; Neward, Ted (2003). C # em poucas palavras . O'Reilly Media, Inc. ISBN 978-0-596-00526-9.
  25. ^ "Sobrecarga do operador C ++" .
  26. ^ "Eclipse Ceylon: Operator Polymorphism" . ceylon-lang.org . Página visitada em 7 de abril de 2021 .
  27. ^ "Operator Overloading - D Programming Language" . dlang.org . Página visitada em 10 de outubro de 2020 .
  28. ^ "Um tour pela linguagem Dart" . dart.dev . Retirado em 30 de setembro de 2020 .
  29. ^ "Sobrecarga do operador" . bourabai.kz . Página visitada em 7 de abril de 2021 .
  30. ^ "A linguagem de programação Apache Groovy - Operadores" . groovy-lang.org . Retirado em 30 de setembro de 2020 .
  31. ^ "Sobrecarga do operador" . Manifold . Página visitada em 7 de junho de 2020 .
  32. ^ "Sobrecarga do operador" . Kotlin . Página visitada em 24 de junho de 2018 .
  33. ^ "Tutorial de Metamétodos" . Wiki dos usuários da Lua .
  34. ^ "Operadores de implementação para sua classe" . Retirado em 1 de outubro de 2013 .
  35. ^ "Sobrecarga do operador" . Manual Pascal grátis . Retirado em 1 de dezembro de 2014 .
  36. ^ "Sobrecarga do operador" . Manual Delphi . Retirado em 1 de dezembro de 2014 .
  37. ^ "Métodos mágicos de PHP sobrescrevendo propriedades de classe" . Arquivado do original em 4 de março de 2016 . Retirado em 7 de abril de 2015 .
  38. ^ Orwant, Jon (4 de novembro de 2002). Ciência da Computação e Programação Perl: Best of The Perl Journal . O'Reilly Media, Inc. pp. 347–. ISBN 978-0-596-00310-4.
  39. ^ "3. Modelo de dados" . A referência da linguagem Python .
  40. ^ "Métodos" . FAQ oficial do Ruby .
  41. ^ "Sobrecarga do operador" . Ferrugem por exemplo .
  42. ^ "Como: Definir um Operador (Visual Basic)" .
  43. ^ Wijngaarden, Adriaan ; Mailloux, Barry J .; Peck, John EL ; Koster, Cornelis HA ; et al. (Agosto de 1968). "Relatório sobre a linguagem algorítmica ALGOL 68, seção 10.2.2" (PDF) . Página visitada em 1 de abril de 2007 .
  44. ^ Stroustrup, Bjarne . "A History of C ++: 1979-1991" (PDF) . p. 12 . Página visitada em 1 de abril de 2007 .
  45. ^ "Pergunta da FAQ 6.9: Por que não há sobrecarga do operador?" . A lista de perguntas frequentes do comp.lang.java .
  46. ^ "java.sun.com" . Arquivado do original em 7 de março de 2009 . Página visitada em 26 de março de 2009 .
  47. ^ Holzner, Steven (2001). C ++: Livro Negro . Scottsdale, Arizona: Coriolis Group. p. 387. ISBN 1-57610-777-9. Um dos melhores recursos do C ++ OOP é que você pode sobrecarregar operadores para manipular objetos de suas classes (você não pode fazer isso em algumas outras linguagens centradas em OOP, como Java).