Programmation • IoT

Résumé – Chap 3 – La sémantique de déplacement

La sémantique de déplacement répond à une situation différente de la copie. Lors d’une copie, l’objet d’origine conserve son contenu tandis qu’un nouvel objet reçoit sa propre copie de la ressource. Cette opération peut devenir coûteuse lorsqu’un objet possède, par exemple, une zone mémoire contenant plusieurs millions de valeurs : il faut allouer une nouvelle zone puis recopier toutes les données. Si l’objet d’origine n’a plus besoin de conserver sa ressource, cette duplication est inutile. Le déplacement consiste alors à transférer la ressource au nouvel objet sans recopier son contenu. L’objet source continue d’exister, mais il ne possède plus nécessairement la ressource transférée. Cette distinction conduit aux catégories d’expressions lvalue et rvalue. Une lvalue désigne typiquement un objet identifiable et persistant auquel on peut revenir, tandis qu’une rvalue correspond notamment à une valeur temporaire ou à une expression dont les ressources peuvent être récupérées. Une référence lvalue s’écrit T&, tandis qu’une référence rvalue s’écrit T&&. Cette dernière permet notamment de sélectionner les opérations prévues pour recevoir une ressource susceptible d’être déplacée.

std::move permet d’indiquer qu’un objet peut être traité comme une source de déplacement, mais son nom peut être trompeur : std::move ne déplace lui-même aucune donnée. Il transforme l’expression de manière à permettre l’appel d’un constructeur ou d’un opérateur d’affectation par déplacement. Un constructeur de déplacement peut alors récupérer les ressources de l’objet source, par exemple son pointeur vers une zone dynamique, puis placer la source dans un état ne possédant plus cette ressource. L’affectation par déplacement applique le même principe à deux objets déjà existants, avec la nécessité pour l’objet destination de libérer auparavant la ressource qu’il possédait. Après un déplacement, l’objet source n’est pas détruit : il continue d’exister et son destructeur sera appelé normalement. Pour les types de la bibliothèque standard, il reste généralement dans un état valide mais dont la valeur n’est pas spécifiée ; dans le cas particulier de std::unique_ptr, son état est précisément défini et le pointeur source devient vide. La sémantique de déplacement permet ainsi de transférer efficacement des ressources et explique pourquoi une propriété exclusive, impossible à copier avec unique_ptr, peut néanmoins être transmise d’un propriétaire à un autre.