Comparaison de la surcharge d'opérateur
Qui 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 >, <, <=, >= je voudrais aller avec la mise en œuvre 2 lorsque cela est possible. Cependant, pour != Je pense que la mise en œuvre 1 est meilleure depuis un autre appel de méthode n'est pas faite, est-ce correct?
- J'aimerais écrire de la façon la plus naturelle d'exprimer cela correctement. Le compilateur va probablement faire un bon travail de compilation de ce qui jamais la manière que vous choisissez.
- Ok merci. Comme une note de côté, je sais que si l' == est trop complexe, alors la mise en œuvre 2 serait mieux, mais c'est une autre affaire.
- Vous devez ajouter un
const
à chacune des fonctions. Pensez aussi à utiliser des fonctions libres plutôt que des fonctions de membre du, que les anciens sont symétriques par rapport à des types et des conversions où ce dernier ne le sont pas. Ce qui est plus important, si votre type peut être implicitement converti à partir d'autres types.
Vous devez vous connecter pour publier un commentaire.
La deuxième mise en œuvre a la notables contrainte
==
sera toujours le booléen en face de!=
. C'est probablement ce que vous voulez, et il rend votre code plus facile à maintenir car vous n'avez qu'à modifier une mise en œuvre de garder les deux dans la synchro.Vous devez toujours utiliser ce que vous avez en cas de surcharge d'opérateurs de comparaison. Les deux seuls vous avez besoin de le définir sont
operator==
etoperator<
. Le reste vous pouvez l'écrire en termes de ces deux. C'est moins sujettes à l'erreur, comme si vous avez une erreur, c'est seulement dans un seul endroit.L'une des principales caractéristiques de la programmation orientée objet est un code de réutilisabilité. Si vous avez déjà écrit le code, pourquoi écrire de nouveau? Tenir à ce que vous avez, et vous n'aurez qu'une chose à tester.
C'est un peu comme la déclaration d'une constante, et ensuite l'utiliser dans plusieurs endroits tout au long de votre fichier.
operator<
. Parce que x == y est logiquement équivalent à !(x < y) && !(y < x).operator<
etoperator==
à partir de zéro si vous souhaitez que tous les opérateurs de comparaison. En C++ STL algorithmes et les conteneurs utilisationoperator==
pour l'égalité et certains utilisentoperator<
comme vous l'avez décrit. Il est vrai que si ils font des choses différentes, vous pourriez avoir quelques résultats surprenants lors de l'utilisation de certains algorithmes.operator<
), et que la classe a besoin des deux. Cependant, je peux penser qu'à une seule raison, en général, qu'ils soient séparés et que c'est que la mise en œuvre deoperator==
en termes deoperator<
serait la cause de deux comparaisons au lieu d'un. Je ne peux pas attendre pour défaut des opérateurs de comparaison, mais ils peuvent rapidement devenir très limitée.<
exprime un ordre linéaire. Mais qui pourrait ne pas être le cas. Par exemple, considérons personnes commandé par généalogique descendancy. Ce n'est pas un ordre linéaire, certaines personnes ne sont pas comparables, c'est à dire pour moi X et mon frère Y niX<Y
niX>Y
détient, c'est à dire qu'ils reviennent tous les deuxfalse
. Donc généralementX<Y
n'est pas équivalent à!(X>=Y)
etX==Y
n'est pas équivalent à!(X<Y) && !(Y<X)
.Mise en œuvre 2 est mieux, car il rend l'utilisation de la déjà défini l'opérateur==. Aussi ces fonctions de l'exploitant doit être
const
parce qu'ils ne modifient pas l'objet.stl_algobase.h:808:22: error: no match for 'operator=='
jusqu'à ce que j'ai déclaré les fonctionsconst
Merci de souligner ce point.Aucun des ci-dessus.
Je souhaite que je pourrais trouver le livre qui va réellement plus de cela dans le détail, mais je ne peux pas me rappeler le nom.
Vos opérations de comparaison doit être externe. Votre interface devrait être suffisant pour trouver l'état d'un objet et de l'état de l'objet devrait dicter la comparaison. Il doit être possible d'écrire "égale" à l'extérieur de votre classe, et donc toute comparaison vraiment, et que c'était possible...vous voulez.
En général, la mise en œuvre 2 est mieux pour de nombreuses raisons. Tout d'abord, vous n'avez pas à écrire (presque) dupliquer le code. Si vous avez besoin de le changer (parce que la classe a augmenté ou il y a eu un bug), à nouveau avec la mise en œuvre 2 vous changez seulement 1 place. Qui est, la mise en œuvre 2 rend votre code plus cohérente et moins sujette aux erreurs.