La copie d'un objet est l'action, en programmation informatique, de reproduire ou copier les attributs d'un objet dans un autre objet. Un objet, le plus souvent est un type de donnée composée dans les langages de programmation orientée objet. Bien que dans les cas simples, copier un objet peut être fait en créant un nouvel objet vierge et en lui assignant tous les attributs de l'objet original, dans des situations plus complexes, cela ne mène pas toujours au résultat attendu.
Copie de référence
Définition
La méthode de copie de référence ou par alias est la copie la plus simple et la plus rapide, il ne s'agit pas réellement d'une copie à proprement parler car on se contente de "déclarer" un nouvel objet relié au même bloc mémoire que l'objet d'origine. Les deux objets portent des noms différents mais représentent exactement la même chose, A ⇔ B, ils ont la même référence.
Cela signifie que :
- Ajouter ou retirer un élément dans B l'ajoutera ou le retirera de A (A reste égal à B)
- Modifier la valeur d'un objet dans B issu de la copie depuis A modifiera également la valeur de cet objet dans A car il s'agit du même objet (copie en référence)
Copie superficielle
Définition
Une méthode de copie d'un objet est la copie superficielle aussi connue en anglais sous le nom de shallow copy.
La copie superficielle B d'un objet A est un nouvel objet ayant une référence ou adresse en mémoire différente de A. Le contenu de A est copié dans B par référence(on change le nom mais pas la référence à l'objet initial). Seul l'objet A est "réellement" copié (un nouvel objet est créé), son contenu quant à lui est seulement une copie de référence.
Cela signifie que :
- Ajouter ou retirer un élément dans B n'aura aucun impact sur A
- Modifier la valeur d'un objet dans B issu de la copie depuis A modifiera également la valeur de cet objet dans A car il s'agit du même objet (copie en référence)
A et B ne font pas référence au même bloc mémoire, modifier l'un n'a donc pas d'impact sur l'autre.
Les objets contenu dans A et B en revanche font référence chacun respectivement au même bloc mémoire que leur original car ce sont des copies de référence. Modifier un objet de B provenant de A modifiera également la valeur de l'objet dans A.
Exemple
Soit A avec pour adresse mémoire 0x000a qui contient les objets a1, a2, a3 avec les adresses mémoire 0x0001, 0x0002, 0x0003.
Une copie superficielle de A dans B donnerait un nouvel objet B avec une adresse mémoire 0x000b (différente de A) qui contiendra les objets b1, b2, b3 ayant pour adresses mémoire 0x0001, 0x0002, 0x0003 (les mêmes que a1, a2, a3).
Notes
Si le langage de programmation n'a pas un ramasse-miettes, l'objet A peut ne plus être utilisé et causer une fuite de mémoire. Il faudra penser à réallouer cet espace de mémoire.
L'avantage de la copie superficielle est que sa vitesse d'exécution est rapide et ne dépend pas de la taille de la donnée car on ne copie pas le contenu mais le contenant.
Les copies bitwise de objets qui ne sont pas composées de blocs monolithiques sont des copies superficielles.
Copie profonde
Définition
En anglais deep copy. La copie profonde est une "vraie" copie de l'objet, B devient complètement indépendant de A.
La copie profonde d'un objet est une copie superficielle pour laquelle en plus de créer un nouvel objet B identique à A mais stocké dans une adresse mémoire différente, on réalise récursivement la copie superficielle de tous les objets contenus dans l'objet A.
Plus aucun objet n'est copié en référence, tous les objets dans B ont une nouvelle adresse mémoire différente de leur originale dans A.
Cela signifie que :
- Ajouter ou retirer un élément dans B n'aura aucun impact sur A
- Modifier la valeur d'un objet dans B issu de la copie depuis A ne modifiera pas la valeur de cet objet dans A car il ne s'agit plus du même objet
A et B ne font pas référence au même bloc mémoire, modifier l'un n'a donc pas d'impact sur l'autre.
Les objets contenus dans A et B ne font plus non plus référence chacun respectivement au même bloc mémoire que leur original car ils sont récursivement copiés en profondeur. Modifier un objet de B provenant de A ne modifiera pas la valeur de l'objet dans A.
Exemple
Soit A avec pour adresse mémoire 0x000a qui contient les objets a1, a2, a3 avec les adresses mémoire 0x0001, 0x0002, 0x0003.
Une copie profonde de A dans B donnera un nouvel objet B avec une adresse mémoire 0x000b (différente de A) qui contiendra les objets b1, b2, b3 ayant pour adresses mémoire 0x0011, 0x0012, 0x0013 (différentes de a1, a2, a3).
Copie paresseuse
En anglais lazy copy. La copie paresseuse est une combinaison des deux stratégies précédentes. Quand initialement on copie un objet, la copie superficielle est utilisée. Un compteur A est utilisé pour tracer combien d'objets partagent la donnée. Quand le programme veut modifier l'objet, il peut déterminer si la donnée est partagée (en examinant le compteur) et peut faire une copie profonde si nécessaire.
La copie paresseuse ressemble à une copie profonde mais peut-être aussi rapide que la copie superficielle dans certains cas.
Dans quelques situations, des références circulaires peuvent causer problèmes.
La copie paresseuse est corollaire à la copy-on-write.
Voir aussi
Liens externes