Los ejemplos obvios de sobrecarga apropiada del operador son las clases que se comportan de la misma manera que operan los números. Por lo tanto, las clases BigInt (como sugiere Jalayn ), los números complejos o las clases matriciales (como sugiere Superbest ) tienen las mismas operaciones que los números ordinarios, por lo que se asignan muy bien a los operadores matemáticos, mientras que las operaciones de tiempo (como lo sugiere svick ) se asignan muy bien a un subconjunto de esas operaciones.
Un poco más abstracto, los operadores podrían usarse al realizar operaciones de conjunto , por lo que operator+
podría ser una unión , operator-
podría ser un complemento, etc. Sin embargo, esto comienza a estirar el paradigma, especialmente si usa el operador de suma o multiplicación para una operación que no es t conmutativo , como es de esperar que sean.
C # en sí tiene un excelente ejemplo de sobrecarga de operadores no numéricos . Utiliza +=
y -=
para sumar y restar delegados , es decir, registrarlos y anular su registro. Esto funciona bien porque los operadores +=
y -=
funcionan como cabría esperar, y esto da como resultado un código mucho más conciso.
Para el purista, uno de los problemas con el +
operador de cadena es que no es conmutativo. "a"+"b"
No es lo mismo que "b"+"a"
. Entendemos esta excepción para las cadenas porque es muy común, pero ¿cómo podemos saber si el uso operator+
en otros tipos será conmutativo o no? La mayoría de las personas supondrá que lo es, a menos que el objeto tenga forma de cadena , pero nunca se sabe realmente qué asumirá la gente.
Al igual que con las cadenas, las debilidades de las matrices también son bastante conocidas. Es obvio que Matrix operator* (double, Matrix)
es una multiplicación escalar, mientras Matrix operator* (Matrix, Matrix)
que sería una multiplicación matricial (es decir, una matriz de multiplicaciones de productos de puntos), por ejemplo.
Del mismo modo, el uso de operadores con delegados está tan alejado de las matemáticas que es poco probable que cometa esos errores.
Por cierto, en la conferencia ACCU 2011 , Roger Orr y Steve Love presentaron una sesión sobre Algunos objetos son más iguales que otros: una mirada a los muchos significados de igualdad, valor e identidad . Sus diapositivas se pueden descargar , al igual que el Apéndice de Richard Harris sobre la igualdad de coma flotante . Resumen: ¡ Ten mucho cuidado con operator==
, aquí hay dragones!
La sobrecarga del operador es una técnica semántica muy poderosa, pero es fácil de usar en exceso. Idealmente, solo debe usarlo en situaciones en las que está muy claro por contexto cuál es el efecto de un operador sobrecargado. En muchos sentidos a.union(b)
es más claro que a+b
, y a*b
es mucho más oscuro que a.cartesianProduct(b)
, especialmente porque el resultado de un producto cartesiano sería SetLike<Tuple<T,T>>
más bien un a SetLike<T>
.
Los problemas reales con la sobrecarga del operador se producen cuando un programador supone que una clase se comportará de una manera, pero en realidad se comportará de otra. Este tipo de choque semántico es lo que sugiero que es importante tratar de evitar.