Les exemples évidents de surcharge d'opérateur appropriée sont toutes les classes qui se comportent de la même manière que les nombres fonctionnent. Ainsi, les classes BigInt (comme le suggère Jalayn ), les nombres complexes ou les classes matricielles (comme le suggère Superbest ) ont toutes les mêmes opérations que les nombres ordinaires si bien mappées très bien sur les opérateurs mathématiques, tandis que les opérations temporelles (comme suggéré par svick ) mappent bien sur un sous-ensemble de ces opérations.
Un peu plus abstraitement, les opérateurs pourraient être utilisés lors de l'exécution d' opérations de type ensemble , donc operator+
pourraient être une union , operator-
un complément, etc. Cela commence à étirer le paradigme, surtout si vous utilisez l'opérateur d'addition ou de multiplication pour une opération qui n'est t commutative , comme on pourrait s'y attendre.
C # lui-même a un excellent exemple de surcharge d'opérateur non numérique . Il utilise +=
et -=
pour ajouter et soustraire des délégués , c'est-à-dire les enregistrer et les désenregistrer. Cela fonctionne bien car les opérateurs +=
et -=
fonctionnent comme vous vous en doutez, ce qui donne un code beaucoup plus concis.
Pour le puriste, l'un des problèmes avec l' +
opérateur de chaîne est qu'il n'est pas commutatif. "a"+"b"
n'est pas le même que "b"+"a"
. Nous comprenons cette exception pour les chaînes car elle est si courante, mais comment savoir si l'utilisation operator+
sur d'autres types sera commutative ou non? La plupart des gens penseront que c'est le cas, à moins que l'objet ne soit semblable à une chaîne , mais vous ne savez jamais vraiment ce que les gens supposeront.
Comme pour les cordes, les faiblesses des matrices sont également assez bien connues. Il est évident que Matrix operator* (double, Matrix)
c'est une multiplication scalaire, alors que ce Matrix operator* (Matrix, Matrix)
serait une multiplication matricielle (c'est-à-dire une matrice de multiplications de produits scalaires) par exemple.
De même, l'utilisation d'opérateurs avec des délégués est tellement loin des mathématiques qu'il est peu probable que vous fassiez ces erreurs.
Soit dit en passant, lors de la conférence ACCU 2011 , Roger Orr et Steve Love ont présenté une session sur Certains objets sont plus égaux que d'autres - un regard sur les nombreuses significations de l'égalité, de la valeur et de l'identité . Leurs diapositives sont téléchargeables , tout comme l' annexe de Richard Harris sur l'égalité en virgule flottante . Résumé: Soyez très prudent avec operator==
, voici des dragons!
La surcharge des opérateurs est une technique sémantique très puissante, mais elle est facile à sur-utiliser. Idéalement, vous ne devriez l'utiliser que dans des situations où il est très clair, d'après le contexte, quel est l'effet d'un opérateur surchargé. À bien des égards, a.union(b)
est plus clair que a+b
, et a*b
est beaucoup plus obscur que a.cartesianProduct(b)
, d'autant plus que le résultat d'un produit cartésien serait un SetLike<Tuple<T,T>>
plutôt qu'un SetLike<T>
.
Les vrais problèmes de surcharge d'opérateur surviennent lorsqu'un programmeur suppose qu'une classe se comportera d'une manière, mais qu'elle se comportera en fait d'une autre. Ce genre de choc sémantique est ce que je suggère qu'il est important d'éviter.