S'il vous plaît écrire une liste de tâches qu'un constructeur de copie et opérateur d'affectation doivent faire en C++ pour maintenir la sécurité d'exception, d'éviter les fuites de mémoire, etc.Liste de contrôle pour l'écriture constructeur de copie et opérateur d'affectation en C++
Répondre
D'abord être sûr que vous avez vraiment besoin de soutenir la copie. La plupart du temps ce n'est pas le cas, et donc désactiver les deux est la voie à suivre.
Parfois, vous devrez toujours fournir une duplication sur une classe à partir d'une hiérarchie polymorphe, dans ce cas: désactiver l'opérateur d'affectation, écrire un constructeur de copie (protégé?) Et fournir une fonction clone virtuelle. Sinon, dans le cas où vous écrivez une classe de valeur, vous êtes de retour au pays de la Forme canonique orthogonale de Coplien. Si vous avez un membre qui ne peut pas être copié de manière triviale, vous devez fournir un constructeur de copie, un destructeur, un opérateur d'affectation et un constructeur par défaut. Cette règle peut être raffinée, voir par exemple: The Law of The Big Two
Je vous recommande également d'avoir un regard sur C++ FAQ regarding assignment operators et au copy-and-swap idiom et à GOTW.
Je ne sais pas à propos de exception en toute sécurité ici mais je vais de cette façon. Imaginons qu'il s'agisse d'un wrapper de tableau structuré. J'espère que ça aide :)
Array(const Array& rhs)
{
mData = NULL;
mSize = rhs.size();
*this = rhs;
}
Array& operator=(const Array& rhs)
{
if(this == &rhs)
{
return *this;
}
int len = rhs.size();
delete[] mData;
mData = new T[len];
for(int i = 0; i < len; ++i)
{
mData[i] = rhs[i];
}
mSize = len;
return *this;
}
Ce code n'est pas exception en toute sécurité. Toujours attribuer avant de libérer! –
Non ce n'est pas. Je n'ai eu aucun problème avec le code de sécurité des exceptions, donc je n'ai jamais eu l'occasion de le pratiquer. Celui ci-dessus est juste un snipper, normalement vous utilisez des conteneurs STL. Veuillez poster votre extrait, j'aimerais le voir. – Nazgob
Il y a beaucoup de bribes dans les liens que j'ai fournis dans ma réponse. BTW, le test empêchant l'auto-affectation est maintenant considéré comme un anti-idiome (maintenant que les exceptions sont mieux comprises) –
Les versions générées par le compilateur fonctionnent dans la plupart des cas.
Vous devez réfléchir un peu plus au problème lorsque votre objet contient un pointeur RAW (un argument pour ne pas avoir de pointeurs RAW). Donc, vous avez un pointeur RAW, la deuxième question est que vous possédez le pointeur (est-il supprimé par vous)? Si oui, vous devrez appliquer la règle de 4.
Posséder plus d'un pointeur RAW devient de plus en plus difficile à faire correctement (L'augmentation de la complexité n'est pas linéaire non plus [mais c'est observationnel et je n'ai pas de statistiques réelles à retour cette déclaration jusqu'à]). Donc, si vous avez plus d'un pointeur RAW pensez à envelopper chacun dans sa propre classe (une certaine forme de pointeur intelligent).
Règle 4: Si un objet est le propriétaire d'un pointeur RAW, vous devez définir les 4 membres suivants pour vous assurer que vous gérez la gestion de la mémoire correctement:
- Constructeur
- Constructor Copie
- Affectation opérateur
- Destructeur
Comment vous définissez ceux-ci dépendra de la situat ions. Mais les choses à surveiller:
- Construction Par défaut: Set pointeur NULL
- Constructor Copy: Utilisez la copie et Swap Ideum pour fournir à la "garantie d'exception forte"
- opérateur d'affectation: Vérifiez l'affectation
- Destructeur: protège contre les exceptions se propageant hors du destructeur.
"Les versions générées par le compilateur fonctionnent dans la plupart des situations." - Selon le type de programmation que vous faites. Même si tout est des pointeurs intelligents, traitant du suivi des ressources et des problèmes d'exception, une copie superficielle peut ne pas être ce que vous voulez sémantiquement. –
Essayez de lire ceci.
http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
est une très bonne analyse de l'opérateur d'affectation
C'est généralement ce que je demanderais dans une interview. Cependant, je vois une fausse hypothèse: que la plupart des objets nécessitent d'être copiables. "Chaque objet dans un système C++ bien conçu a un constructeur par défaut, un constructeur de copie et un opérateur d'affectation." Cette phrase est pour les objets basés sur la valeur, pas pour les entités. –
- 1. constructeur Copie: copie en profondeur une classe abstraite
- 2. Constructeur de copie de base non appelé
- 3. opérateur OR en C#
- 4. Question à propos de la copie superficielle en C++
- 5. Modèle pour copie rapide en C
- 6. Problèmes lors de l'écriture d'un constructeur de copie pour un pointeur intelligent
- 7. Un pointeur de fonction membre appelle un constructeur de copie?
- 8. appel constructeur de base en C#
- 9. problème constructeur de C
- 10. Sous-classe de QObject, qRegisterMetaType et le constructeur de copie privée
- 11. Menu contextuel de copie pour le contrôle ListView
- 12. C++ vide Constructeur de chaîne
- 13. Attraper des exceptions de la liste d'initialisation d'un constructeur
- 14. Optimisation du constructeur de la copie par rapport à l'optimisation de la valeur de retour
- 15. Opérateur de modèle << instanciation explicite et en-tête
- 16. opérateur Surcharge en C++ comme int + obj
- 17. C# ?? opérateur à Ruby?
- 18. PHP et ?? opérateur
- 19. objectif c opérateur sens
- 20. Essayer de comprendre format binaire copie de Postgres en C#
- 21. Opérateur d'assignation de modèle: C++ valide?
- 22. Contrôle de liste
- 23. C#: l'objet HtmlDocument n'a pas de constructeur?
- 24. C++: Modèle de statut et de contrôle
- 25. Opérateur dynamique C#
- 26. Comment puis-je appeler dynamiquement un constructeur en C#?
- 27. Contrôle de liste déroulante à liste double
- 28. Copie en bloc et suppression dans OneTransaction
- 29. Opérateur de liaison nouveau?
- 30. Forme spécifique du constructeur en C#
Je pensais qu'il s'appelait la règle de 4. –
AFAIK, il provient du livre de Jim Coplien, d'où le nom - BTW il s'applique uniquement aux classes de valeur. Certains l'appellent la règle de quatre. Il y a (était?) Aussi des explications sur/Rule of Big Three/en C++ FAQ lite (je ne le trouve plus). Et il peut être réduit à deux grâce à RAII. –
Protège également contre l'auto-affectation dans l'opérateur d'affectation. –