En la programación de computadoras , la sobrecarga de operadores , a veces denominada polimorfismo ad hoc de operadores , es un caso específico de polimorfismo , donde diferentes operadores tienen diferentes implementaciones dependiendo de sus argumentos. La sobrecarga del operador generalmente se define mediante un lenguaje de programación , un programador o ambos.
Razón fundamental
La sobrecarga de operadores es un azúcar sintáctico y se usa porque permite programar usando una notación más cercana al dominio de destino [1] y permite que los tipos definidos por el usuario tengan un nivel similar de soporte sintáctico como los tipos integrados en un lenguaje. Es común, por ejemplo, en la informática científica, donde permite manipular representaciones informáticas de objetos matemáticos con la misma sintaxis que en papel.
La sobrecarga del operador no cambia el poder expresivo de un lenguaje (con funciones), ya que se puede emular mediante llamadas a funciones. Por ejemplo, considerar variables a
, b
y c
de algún tipo definido por el usuario, tales como matrices :
a + b * c
En un lenguaje que admite la sobrecarga de operadores, y con la suposición habitual de que el operador '*' tiene mayor precedencia que el operador '+', esta es una forma concisa de escribir:
Add(a, Multiply(b, c))
Sin embargo, la sintaxis anterior refleja el uso matemático común.
Ejemplos de
En este caso, el operador de adición está sobrecargado para permitir la adición en un tipo definido por el usuario Time
en C ++ :
Operador de tiempo + ( const Time & lhs , const Time & rhs ) { Time temp = lhs ; temp . segundos + = dcha . segundos ; temp . minutos + = temp . segundos / 60 ; temp . segundos % = 60 ; temp . minutos + = dcha . minutos ; temp . horas + = temp . minutos / 60 ; temp . minutos % = 60 ; temp . horas + = dcha . horas ; temperatura de retorno ; }
La suma es una operación binaria , lo que significa que tiene dos operandos . En C ++, los argumentos que se pasan son los operandos y el temp
objeto es el valor devuelto.
La operación también podría definirse como un método de clase, reemplazando lhs
por el this
argumento oculto ; Sin embargo, esto obliga al operando izquierdo a ser de tipo Time
:
// La "const" justo antes de la llave de apertura significa que | this | no se modifica. Tiempo Tiempo :: operador + ( const Tiempo & rhs ) const { Tiempo temp = * this ; // | esto | no debe modificarse, así que haga una copia. temp . segundos + = dcha . segundos ; temp . minutos + = temp . segundos / 60 ; temp . segundos % = 60 ; temp . minutos + = dcha . minutos ; temp . horas + = temp . minutos / 60 ; temp . minutos % = 60 ; temp . horas + = dcha . horas ; temperatura de retorno ; }
Tenga en cuenta que un operador unario definido como un método de clase no recibiría ningún argumento aparente (solo funciona desde this
):
bool Time :: operator ! () const { horas de retorno == 0 && minutos == 0 && segundos == 0 ; }
El operador menor que (<) suele estar sobrecargado para ordenar una estructura o clase:
class Pair { public : bool operator < ( const Pair & p ) const { if ( x_ == p . x_ ) { return y_ < p . y_ ; } devuelve x_ < p . x_ ; } privado : int x_ ; int y_ ; };
Al igual que en los ejemplos anteriores, en el último ejemplo, la sobrecarga de operadores se realiza dentro de la clase. En C ++, después de sobrecargar el operador menor que (<), se pueden usar funciones de ordenación estándar para ordenar algunas clases.
Criticas
La sobrecarga de operadores a menudo ha sido criticada [2] porque permite a los programadores reasignar la semántica de los operadores dependiendo de los tipos de sus operandos. Por ejemplo, el uso del <<
operador en C ++ desplaza los bits de la variable a la izquierda en bits si y son de tipo entero, pero si es un flujo de salida, el código anterior intentará escribir a en el flujo. Debido a que la sobrecarga de operadores permite al programador original cambiar la semántica habitual de un operador y tomar por sorpresa a los programadores posteriores, se considera una buena práctica utilizar la sobrecarga de operadores con cuidado (los creadores de Java decidieron no utilizar esta función, [3] aunque no necesariamente por esta razón).a << b
a
b
a
b
a
b
Otro problema más sutil con los operadores es que ciertas reglas de las matemáticas pueden esperarse erróneamente o asumirse involuntariamente. Por ejemplo, la conmutatividad de + (es decir, eso a + b == b + a
) no siempre se aplica; un ejemplo de esto ocurre cuando los operandos son cadenas, ya que + comúnmente se sobrecarga para realizar una concatenación de cadenas (es decir , "bird" + "song"
produce "birdsong"
, mientras que "song" + "bird"
produce "songbird"
). Una típica contra [ cita requerida ] a este argumento proviene directamente de las matemáticas: mientras que + es conmutativo en enteros (y más generalmente cualquier número complejo), no es conmutativo para otros "tipos" de variables. En la práctica, + ni siquiera es siempre asociativo , por ejemplo, con valores de coma flotante debido a errores de redondeo. Otro ejemplo: en matemáticas, la multiplicación es conmutativa para números reales y complejos, pero no conmutativa en la multiplicación de matrices .
Catalogar
Se hace una clasificación de algunos lenguajes de programación comunes según si el programador puede sobrecargar sus operadores y si los operadores están limitados a un conjunto predefinido.
Operadores | No se puede sobrecargar | Sobrecargable |
---|---|---|
Nuevo definible [4] | ||
Conjunto limitado |
|
|
Cronología de la sobrecarga del operador
1960
La especificación ALGOL 68 permitió la sobrecarga del operador. [43]
Extracto de la especificación de lenguaje ALGOL 68 (página 177) donde se definen los operadores sobrecargados ¬, =, ≠ y abs :
10.2.2. Operaciones sobre operandos booleanosa) op ∨ = ( bool a, b) bool :( a | true | b);b) op ∧ = ( bool a, b) bool : (a | b | falso );c) op ¬ = ( bool a) bool : (a | falso | verdadero );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);
Tenga en cuenta que no se necesita una declaración especial para sobrecargar un operador, y el programador es libre de crear nuevos operadores.
Decenio de 1980
Ada soporta la sobrecarga de operadores desde sus inicios, con la publicación del estándar de lenguaje Ada 83. Sin embargo, los diseñadores del lenguaje optaron por excluir la definición de nuevos operadores. Solo los operadores existentes en el idioma pueden sobrecargarse al definir nuevas funciones con identificadores como "+", "*", "&", etc. Las revisiones posteriores del idioma (en 1995 y 2005) mantienen la restricción a la sobrecarga de operadores existentes .
En C ++ , la sobrecarga de operadores es más refinada que en ALGOL 68 . [44]
Decenio de 1990
Los diseñadores de lenguajes Java de Sun Microsystems optaron por omitir la sobrecarga. [45] [46] [47]
Ruby permite la sobrecarga del operador como azúcar sintáctico para llamadas a métodos simples.
Lua permite la sobrecarga de operadores como azúcar sintáctico para llamadas a métodos con la característica agregada de que si el primer operando no define ese operador, se usará el método para el segundo operando.
2000
Microsoft agregó la sobrecarga de operadores a C # en 2001 y a Visual Basic .NET en 2003.
Scala trata a todos los operadores como métodos y, por lo tanto, permite la sobrecarga de operadores por proxy.
En Raku , la definición de todos los operadores se delega a funciones léxicas, por lo que, al usar definiciones de función, los operadores pueden sobrecargarse o agregarse nuevos operadores. Por ejemplo, la función definida en la fuente Rakudo para incrementar un objeto Date con "+" es:
multi infijo: <+> ( Fecha: D $ d , Int: D $ x ) { Fecha . new-from-daycount ( $ d . daycount + $ x )}
Dado que se usó "multi", la función se agrega a la lista de candidatos de envío múltiple , y "+" solo se sobrecarga en el caso en que se cumplan las restricciones de tipo en la firma de la función. Si bien la capacidad de sobrecarga incluye + , * , > = , el sufijo y el término i , etc., también permite sobrecargar varios operadores de llaves: " [ x, y ] ", "x [ y ] ", "x { y } "y" x ( y ) ".
Kotlin ha admitido la sobrecarga de operadores desde su creación.
Ver también
- Sobrecarga de funciones
- Polimorfismo (informática)
- Subrutina
- Operador (programación)
- Operadores en C y C ++
- Método de mutador
- Indexador (programación)
- Propiedad (programación)
Referencias
- ^ Stroustrup, Bjarne . "Sobrecarga del operador" . Preguntas frecuentes de C ++ . Archivado desde el original el 14 de agosto de 2011 . Consultado el 27 de agosto de 2020 .
- ^ Fisher, Charles N. (2008). "Problemas de sobrecarga" (PDF) . Universidad de Wisconsin – Madison .
- ^ "No más sobrecarga del operador" . El entorno del lenguaje Java . Oracle Corporation .
- ^ Se pueden agregar operadores completamente nuevos.
- ^ Las funciones binarias con un nombre simbólico se pueden llamar infijo.
- ^ "Predicado op / 3" .
- ^ Hunt, John (6 de diciembre de 2012). Smalltalk y orientación a objetos: una introducción . Springer Science & Business Media. ISBN 978-1-4471-0961-7.
- ^ "Bertrand Meyer: mecanismos básicos del lenguaje Eiffel" . se.ethz.ch . Consultado el 7 de abril de 2021 .
- ^ www.mathcs.emory.edu http://www.mathcs.emory.edu/~cheung/Courses/561/Syllabus/6-Fortran/operators.html . Consultado el 7 de abril de 2021 . Falta o vacío
|title=
( ayuda ) - ^ Introducido en Fortran 90.
- ^ "3. Referencia de idioma - Documentación de Futhark 0.19.0" . futhark.readthedocs.io . Consultado el 10 de octubre de 2020 .
- ^ Smith, Chris (9 de octubre de 2012). Programación F # 3.0: una guía completa para escribir código simple para resolver problemas complejos . O'Reilly Media, Inc. ISBN 978-1-4493-2604-3.
- ^ Escriba clases en lugar de sobrecargar.
- ^ "guía io" . iolanguage.org . Consultado el 7 de abril de 2021 .
- ^ "Operadores - R en pocas palabras, 2ª edición [Libro]" . www.oreilly.com . Consultado el 7 de abril de 2021 .
- ^ "Creación de operadores" .
- ^ "Operadores" . Tour de Scala .
- ^ "Manual de Seed7: Definición de sintaxis estructurada" . seed7.sourceforge.net . Consultado el 29 de septiembre de 2020 .
- ^ "Swift: operadores avanzados" .
- ^ "¿Por qué Go no admite la sobrecarga de métodos y operadores?" . Consultado el 4 de septiembre de 2011 .
- ^ "Introducción" . freepascal.org . Consultado el 30 de septiembre de 2020 .
- ^ "Sobrecargas del operador" . Consultado el 28 de septiembre de 2018 .
- ^ "6.6 Sobrecarga de operadores" . Manual de referencia de Ada anotado .
- ^ Drayton, Peter; Albahari, Ben; Neward, Ted (2003). C # en pocas palabras . O'Reilly Media, Inc. ISBN 978-0-596-00526-9.
- ^ "Sobrecarga del operador C ++" .
- ^ "Eclipse Ceilán: polimorfismo del operador" . ceylon-lang.org . Consultado el 7 de abril de 2021 .
- ^ "Sobrecarga del operador - Lenguaje de programación D" . dlang.org . Consultado el 10 de octubre de 2020 .
- ^ "Un recorrido por el idioma Dart" . dart.dev . Consultado el 30 de septiembre de 2020 .
- ^ "Sobrecarga del operador" . bourabai.kz . Consultado el 7 de abril de 2021 .
- ^ "El lenguaje de programación Apache Groovy - Operadores" . groovy-lang.org . Consultado el 30 de septiembre de 2020 .
- ^ "Sobrecarga del operador" . Colector . Consultado el 7 de junio de 2020 .
- ^ "Sobrecarga del operador" . Kotlin . Consultado el 24 de junio de 2018 .
- ^ "Tutorial de Metamétodos" . Wiki de usuarios de Lua .
- ^ "Implementación de operadores para su clase" . Consultado el 1 de octubre de 2013 .
- ^ "Sobrecarga del operador" . Manual de Pascal gratuito . Consultado el 1 de diciembre de 2014 .
- ^ "Sobrecarga del operador" . Manual de Delphi . Consultado el 1 de diciembre de 2014 .
- ^ "Métodos mágicos de PHP que anulan las propiedades de la clase" . Archivado desde el original el 4 de marzo de 2016 . Consultado el 7 de abril de 2015 .
- ^ Orwant, Jon (4 de noviembre de 2002). Ciencias de la Computación y Programación Perl: Lo mejor de The Perl Journal . O'Reilly Media, Inc. págs. 347–. ISBN 978-0-596-00310-4.
- ^ "3. Modelo de datos" . La referencia del lenguaje Python .
- ^ "Métodos" . Preguntas frecuentes oficiales de Ruby .
- ^ "Sobrecarga del operador" . Óxido por ejemplo .
- ^ "Cómo: definir un operador (Visual Basic)" .
- ^ Wijngaarden, Adriaan ; Mailloux, Barry J .; Peck, John EL ; Koster, Cornelis HA ; et al. (Agosto de 1968). "Informe sobre el lenguaje algorítmico ALGOL 68, sección 10.2.2" (PDF) . Consultado el 1 de abril de 2007 .
- ^ Stroustrup, Bjarne . "Una historia de C ++: 1979-1991" (PDF) . pag. 12 . Consultado el 1 de abril de 2007 .
- ^ "Pregunta frecuente 6.9: ¿Por qué no hay sobrecarga del operador?" . La lista de preguntas frecuentes de comp.lang.java .
- ^ "java.sun.com" . Archivado desde el original el 7 de marzo de 2009 . Consultado el 26 de marzo de 2009 .
- ^ Holzner, Steven (2001). C ++: Libro negro . Scottsdale, Arizona: Grupo Coriolis. pag. 387. ISBN 1-57610-777-9.
Una de las mejores características de C ++ OOP es que puede sobrecargar operadores para manejar objetos de sus clases (no puede hacer esto en algunos otros lenguajes centrados en OOP, como Java).