Quelque chose qui me dérange à propos de:
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
swap(tmp);
return *this;
}
Tout d'abord, la lecture de la parole "swap" quand mon esprit est la pensée de la "copie" irrite mon bon sens. Aussi, je m'interroge sur le but de cette fantaisie truc. Oui, toutes les exceptions dans la construction de la nouvelle (copie) des ressources devrait se faire avant le swap, ce qui semble être un moyen sûr de s'assurer que toutes les nouvelles données est rempli avant de le faire vivre.
C'est très bien. Donc, concernant les exceptions qui se produisent après l'échange? (quand la vieille ressources sont détruits lorsque l'objet temporaire est hors de portée) du point De vue de l'utilisateur de la mission, l'opération a échoué, sauf qu'il n'a pas. Il a un énorme effet de bord: la copie ne se produisent réellement. C'était seulement un nettoyage des ressources qui a échoué. L'état de l'objet de destination a été modifié, même si l'opération semble de l'extérieur d'avoir échoué.
Donc, je propose plutôt de "swap" pour faire plus naturel "transfert":
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
transfer(tmp);
return *this;
}
Il y a encore de la construction de l'objet temporaire, mais la prochaine action immédiate est de libérer toutes les ressources actuelles de la destination, avant de se déplacer (et Invalide donc ils ne seront pas en double-libéré) les ressources de la source.
Au lieu de { construire, de se déplacer, détruire }, je propose { construire, détruire, déplacer }. Le mouvement, qui est le plus dangereux de l'action, qui est pris en dernier après que tout a été réglé.
Oui, la destruction échouer est un problème dans l'un des deux systèmes. Les données sont endommagées (copiées lorsque vous ne pensiez pas que c'était) ou de perte (libéré lorsque vous ne pensiez pas que c'était). Perdu, c'est mieux que corrompu. Aucune donnée n'est mieux que de mauvaises données.
Transfert au lieu de swap. C'est ma suggestion de toute façon.