unique_ptr
n'est pas copiable, il est uniquement déplaçable.
Cela affectera directement Test, qui est, dans votre deuxième exemple, également uniquement mobile et non copiable.
En fait, il est bon que vous utilisiez unique_ptr
ce qui vous protège d'une grosse erreur.
Par exemple, le principal problème avec votre premier code est que le pointeur n'est jamais supprimé, ce qui est vraiment très mauvais. Dites, vous régleriez cela en:
class Test
{
int* ptr; // writing this in one line is meh, not sure if even standard C++
Test() : ptr(new int(10)) {}
~Test() {delete ptr;}
};
int main()
{
Test o;
Test t = o;
}
C'est également mauvais. Que se passe-t-il si vous copiez Test
? Il y aura deux classes qui ont un pointeur qui pointe vers la même adresse.
Quand on Test
est détruit, cela détruira également le pointeur. Lorsque votre deuxième Test
est détruit, il essaiera également de supprimer la mémoire derrière le pointeur. Mais il a déjà été supprimé et nous obtiendrons une mauvaise erreur d'exécution d'accès à la mémoire (ou un comportement indéfini si nous ne sommes pas chanceux).
Donc, la bonne façon est d'implémenter le constructeur de copie et l'opérateur d'affectation de copie, de sorte que le comportement soit clair et que nous puissions créer une copie.
unique_ptr
est bien en avance sur nous ici. Il a la signification sémantique: " Je suis unique
, donc vous ne pouvez pas simplement me copier. " Donc, cela nous évite de l'erreur d'implémenter maintenant les opérateurs à portée de main.
Vous pouvez définir le constructeur de copie et l'opérateur d'affectation de copie pour un comportement spécial et votre code fonctionnera. Mais vous êtes, à juste titre (!), Obligé de le faire.
La morale de l'histoire: toujours utiliser unique_ptr
dans ce genre de situations.