lorill a écrit :
Bon, résumé de la situation. J'ai un ptit langage de programmation qui marchote. La dedans, j'ai des objets. Et je voudrais bien les cloner.
|
2 solutions : deep copy ou swallow copy.
le principe swallow copy (copie en surface) : tu copies l'objet brutalement en recopiant les références.
Code :
- objetA-------->objetB
- copieA---------^
|
ça on sait faire, c'est facile.
deep copy (copie profonde) : tu copies l'objet et les objets qu'il référence.
Code :
- objetA-------->objetB
- copieA-------->copieB
|
ça c'est plus chiant, car tu va suivre des références.
donc la configuration suivante :
Code :
- objetA-------->objetB----->objetC-,
- ^---------------------------------'
|
devrait raisonablement envoyer ton algo dans l'espace.
C'est la présence de cycles qui fout la merde.
Il faut un détecteur de cycles ; le plus simple est un marquage des objets copiés. Tu prends un objet, s'il est pas marqué tu le copies et tu le marques, sinon tu le copies pas, tu t'arrêtes.
Il existe un autre algo, le lièvre et la tortue, mais je vois pas comment l'appliquer à ce cas.
Bien entendu, comme c'est un graphe plus complexe, ton algo doit être plus chiadé :
- parcours en largeur ; lorsque tu es "bloqué" (fin de cycle ou feuille) tu reprends le suivant dans la file (j'espère que tu sais faire un parcour en largeur).
- parcours en profondeur ; lorsque tu es "bloqué" tu remontes dans le graphe jusqu'à trouver un objet dont un des champs n'a pas été copié. Je te déconseille fortement d'implanter cet algo en version récursive.
D'autre part, si tu es en monotache, tu peux éventuellement mettre en dur le champ de marquage des objets dans les entêtes (mais fait bien gaffe par la suite, c'est pas réentrant). Sinon, tu utilises un ensemble par identité (identitySet) dans un itérateur (c'est réentrant et propre mais ça bouffe de la mémoire).
Pour des exemples de code : Object#deepCopy et Object#swalowCopy de smalltalk.