clonage d'objets

clonage d'objets - Algo - Programmation

Marsh Posté le 15-05-2003 à 14:40:12    

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.  
 
Les objets sont représentés en C par une structure, contenant une table des attributs accessibles du langage, et des données C.
 
Bon. Pour cloner, j'avais pensé a ca :

Code :
  1. methode clone():
  2. racineDuClonage = faux
  3. si contexte.enCoursDeClonage() est faux:
  4.    context.initClonage()
  5.    racineDuClonage = vrai
  6. si contexte.dejaCloné(self):
  7.    return contexte.cloneDuPointeur(self)
  8. copie = Object.create()
  9. contexte.memoriseClone(self, copie)
  10. pour chaque membre M de la structure clonée:
  11.    copie.M = M.clone()
  12. si racineDuClonage:
  13.    contexte.resetClonage()
  14. retourne copie


 
hélas, comme kadreg< me l'a fait remarquer, l'algo est faux (trop simpliste)
 

kadreg a écrit :


parcequ'il fait pas de différence entre association, composition et aggregation. Il présuppose que tout est composition, et c'est loin d'être toujours le cas.
 
 


--------------       --------        ---------
| Professeur | ----> |classe| -----> | eleve |
--------------       --------        ---------


 
J'aimerais que si tu clone un professeur, qu'il ne me clone pas tous les élève de toutes les classes auquel ce professeur donne court.


 
ce quoi j'ai repondu :
 

lorill a écrit :


ha oui, tiens [:gratgrat]
mince.
 
comment je vais distinguer ca de :


--------------         --------------          ----------
| Hashtable  |  ----<> | Professeur | -----<#> | String |
--------------         --------------          ----------


 
c'est plus complexe que ce que je pensais :/  


 
 
une solution de fénéant que je vois serait de préciser lors du rattachement de l'attribut a l'objet si cet attribut fait partie de l'objet ou si ce n'est que la représentation d'une relation.
 
mais bof... des avis ?

Reply

Marsh Posté le 15-05-2003 à 14:40:12   

Reply

Marsh Posté le 15-05-2003 à 19:28:27    

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 :
  1. objetA-------->objetB
  2. 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 :
  1. objetA-------->objetB
  2. copieA-------->copieB


ça c'est plus chiant, car tu va suivre des références.
donc la configuration suivante :

Code :
  1. objetA-------->objetB----->objetC-,
  2. ^---------------------------------'


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.

Reply

Marsh Posté le 15-05-2003 à 19:31:05    

en fait moi c'est un clonage en profondeur que je veux (deep copy, donc).
 
la gestion des cycles, je pense gérer ca comme dans mon algo au premier post. Le probleme, c'est plus de savoir si je dois cloner un objet ou juste copier sa réference selon le cas.

Reply

Marsh Posté le 15-05-2003 à 19:37:11    

lorill a écrit :

en fait moi c'est un clonage en profondeur que je veux (deep copy, donc).
 
la gestion des cycles, je pense gérer ca comme dans mon algo au premier post. Le probleme, c'est plus de savoir si je dois cloner un objet ou juste copier sa réference selon le cas.


http://java.sun.com/j2se/1.4.1/doc [...] ml#clone()
mais sans hiérarchie ça me parraît dur.
donc tag sur les champs.

Reply

Marsh Posté le 15-05-2003 à 19:42:29    

nraynaud a écrit :


donc tag sur les champs.


c'est a dire (tagger quoi ?) ?
marquer le fait que le champs soit "a cloner" ou tu penses a autre chose ?

Reply

Marsh Posté le 15-05-2003 à 19:46:09    

lorill a écrit :


c'est a dire (tagger quoi ?) ?
marquer le fait que le champs soit "a cloner" ou tu penses a autre chose ?


non, c'est ça.
 
à moins que tu n'aies un moyen d'appeler la fonction que tu est en train de réecrire dans ton langage (l'équivalent de super() en java), ce qui me parraît peu probable.

Reply

Marsh Posté le 15-05-2003 à 19:49:34    

nraynaud a écrit :


 
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.

shallow copy!
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 15-05-2003 à 19:53:31    

nraynaud a écrit :


non, c'est ça.


ok, c'est la solution que j'avais envisagé fin du premier message, donc.
 
par contre je vois pas comment cloner sans récursion :??:
parce qu'en fait, les objets du langage, ca va, je peux les recuperer en iterant, mais j'ai aucun moyen de savoir si j'ai un char* a copier dans la structure, en dehors de la table des attributs...

Reply

Marsh Posté le 15-05-2003 à 19:54:15    

gilou a écrit :

shallow copy!
A+,


gloups en plus je viens de le voir passer dans google donc shamallow copy mais gaffe à pas s'étouffer.
 
Au fait, ça à rien à foutre dans algo cette discussion, j'ai passé 20min à répondre à côté de la plaque à cause de ça.

Reply

Marsh Posté le 15-05-2003 à 19:55:17    

nraynaud a écrit :


Au fait, ça à rien à foutre dans algo cette discussion, j'ai passé 20min à répondre à côté de la plaque à cause de ça.


 
ben si, quand meme... tu le mettrais ou sinon ?

Reply

Marsh Posté le 15-05-2003 à 19:55:17   

Reply

Marsh Posté le 15-05-2003 à 19:56:47    

lorill a écrit :


parce qu'en fait, les objets du langage, ca va, je peux les recuperer en iterant, mais j'ai aucun moyen de savoir si j'ai un char* a copier dans la structure, en dehors de la table des attributs...


"Maître, reformulez votre question."
 
J'ai pas compris.

Reply

Marsh Posté le 15-05-2003 à 19:58:38    

lorill a écrit :


 
ben si, quand meme... tu le mettrais ou sinon ?


Divers, y'a rien pour la conception des langages ici.

Reply

Marsh Posté le 15-05-2003 à 20:01:21    

prenons une String par exemple :
dedans j'ai ca :
 - StringTable * attributes (héritée d'Object)
 - char * value
 
maintenant un Integer :
 - StringTable * attributes
 - mpz_t value
 
si j'itere, je peux avoir une variable de type Object. Donc je peux cloner tout ce qui rentre dans la StringTable (les attributs). Par contre, impossible de savoir comment copier le reste.
 
Il me faut donc une implémentation par type, et appeller recursivement ces différentes méthodes clone().
 
C'est plus clair ?

Reply

Marsh Posté le 15-05-2003 à 20:10:12    

lorill a écrit :


C'est plus clair ?


pas trop, tes exemples sont des types primitifs, il faut toujours trafiquer pour les types primitifs.
Mais un objet normal (pas integer, pas string, pas float, pas bool, pas référence faible et pas tableau), ça a quelle tête ?

Reply

Marsh Posté le 15-05-2003 à 20:11:58    

nraynaud a écrit :


pas trop, tes exemples sont des types primitifs, il faut toujours trafiquer pour les types primitifs.
Mais un objet normal (pas integer, pas string, pas float, pas bool, pas référence faible et pas tableau), ça a quelle tête ?


ha, ca c'est pas un probleme, y'a que les types primitifs qui sont chiants :o
 
un objet normal, c'est juste un type primitif avec des attributs en plus (des entrees supplémentaires dans la StringTable, donc). Du coup, la méthode clone() du type primitif duquel est dérivé l'objet s'applique

Reply

Marsh Posté le 15-05-2003 à 20:14:50    

lorill a écrit :


ha, ca c'est pas un probleme, y'a que les types primitifs qui sont chiants :o
 
un objet normal, c'est juste un type primitif avec des attributs en plus (des entrees supplémentaires dans la StringTable, donc). Du coup, la méthode clone() du type primitif duquel est dérivé l'objet s'applique


ok, alors fais-le récursivement.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed