web-dev-qa-db-fra.com

Surcharge d'opérateur de comparaison

Quelle est la meilleure pratique (dans ce cas):

bool Foo::operator==(const Foo& other) {
  return bar == other.bar;
}

// Implementation 1
bool Foo::operator!=(const Foo& other) {
  return bar != other.bar
}

// Implementation 2
bool Foo::operator!=(const Foo& other) {
  return !(*this == other);
}

Pour les opérateurs comme>, <, <=,> = j'irais avec l'implémentation 2 lorsque cela est possible. Cependant, pour! = Je pense que l'implémentation 1 est meilleure car aucun autre appel de méthode n'est effectué, est-ce correct?

35
blaze

La deuxième implémentation a la contrainte notable que == sera toujours l'opposé booléen de !=. C'est probablement ce que vous voulez, et cela rend votre code plus facile à maintenir car vous n'avez qu'à modifier une implémentation pour les synchroniser.

32
zneak

Vous devez toujours utiliser ce que vous avez lors de la surcharge des opérateurs de comparaison. Les deux seuls que vous devez définir sont operator== et operator<. Le reste, vous pouvez écrire en termes de ces deux. C'est moins sujet aux erreurs, comme si vous avez une erreur, ce n'est qu'à un seul endroit.

L'une des principales caractéristiques de OOP est la réutilisabilité du code. Si vous avez déjà écrit le code, pourquoi le réécrire? Restez fidèle à ce que vous avez, et vous n'aurez qu'une chose à tester .

C'est un peu comme déclarer une constante, puis l'utiliser à plusieurs endroits dans votre fichier.

12
chris

L'implémentation 2 est meilleure car elle utilise l'opérateur déjà défini ==. Ces fonctions d'opérateur doivent également être const car elles ne modifient pas l'objet.

4
sashang

Aucune de ces réponses.

J'aurais aimé pouvoir trouver le document qui traite vraiment de cela en détail, mais je ne me souviens pas du nom.

Vos opérations de comparaison doivent être externes. Votre interface doit être suffisante pour trouver l'état d'un objet et l'état de l'objet doit dicter la comparaison. Il devrait être possible d'écrire "égaux" en dehors de votre classe, et donc vraiment n'importe quelle comparaison, et cela étant possible ... vous voulez.

3
Edward Strange

En général, l'implémentation 2 est meilleure pour de nombreuses raisons. Tout d'abord, vous n'écrivez pas (presque) de code en double. Si vous devez le changer (parce que la classe a grandi ou qu'il y a eu un bug), encore une fois avec l'implémentation 2, vous ne changez qu'un seul endroit. Autrement dit, l'implémentation 2 rend votre code plus cohérent et moins sujet aux erreurs.

2
Shahbaz