Os exemplos óbvios de sobrecarga adequada do operador são quaisquer classes que se comportam da mesma maneira que os números operam. Portanto, as classes BigInt (como sugere Jalayn ), os números complexos ou as classes matriciais (como sugere Superbest ), todas têm as mesmas operações que os números comuns, portanto, mapeiam muito bem os operadores matemáticos, enquanto as operações de tempo (como sugerido por svick ) mapeiam muito bem um subconjunto dessas operações.
Um pouco mais abstratamente, os operadores podem ser usados ao executar operações definidas , assim, operator+
podem ser uma união , operator-
podem ser um complemento etc. Isso começa a esticar o paradigma, especialmente se você usar o operador de adição ou multiplicação para uma operação que não é ' t comutativa , como você pode esperar que eles sejam.
O próprio C # possui um excelente exemplo de sobrecarga não numérica do operador. Ele usa +=
e -=
adiciona e subtrai delegados , ou seja, registra e cancela o registro. Isso funciona bem porque os operadores +=
e -=
funcionam como você esperaria, e isso resulta em um código muito mais conciso.
Para o purista, um dos problemas com o +
operador de string é que ele não é comutativo. "a"+"b"
não é o mesmo que "b"+"a"
. Entendemos essa exceção para strings porque é muito comum, mas como podemos saber se o uso operator+
em outros tipos será comutativo ou não? A maioria das pessoas assume que sim, a menos que o objeto seja do tipo string , mas você nunca sabe realmente o que as pessoas assumirão.
Como nas cordas, os pontos fracos das matrizes também são bastante conhecidos. É óbvio que Matrix operator* (double, Matrix)
é uma multiplicação escalar, ao passo que Matrix operator* (Matrix, Matrix)
seria uma multiplicação de matrizes (por exemplo, uma matriz de multiplicações de produtos pontuais).
Da mesma forma, o uso de operadores com delegados está tão obviamente distante da matemática que é improvável que você cometa esses erros.
Aliás, na conferência da ACCU de 2011 , Roger Orr e Steve Love apresentaram uma sessão sobre Alguns objetos são mais iguais que outros - uma olhada nos muitos significados de igualdade, valor e identidade . Seus slides podem ser baixados , assim como o Apêndice de Richard Harris sobre igualdade de ponto flutuante . Resumo: Tenha muito cuidado com operator==
, aqui estão os dragões!
A sobrecarga do operador é uma técnica semântica muito poderosa, mas é fácil de usar em excesso. Idealmente, você deve usá-lo apenas em situações em que o contexto de um operador sobrecarregado seja muito claro. De muitas maneiras a.union(b)
é mais clara do que a+b
, e a*b
é muito mais obscura do que a.cartesianProduct(b)
, especialmente desde que o resultado de um produto cartesiano seria um SetLike<Tuple<T,T>>
em vez de um SetLike<T>
.
Os problemas reais com sobrecarga do operador ocorrem quando um programador assume que uma classe se comportará de uma maneira, mas na verdade se comporta de outra. Esse tipo de conflito semântico é o que estou sugerindo que é importante tentar evitar.