Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Copier un Objet

16 réponses
Avatar
Pascal B.
Bonjour à tous,

(je sais pas si je vais être clair... bon je me lance)

J'aimerais pouvoir créer une copie d'un objet.
Ce qui vient en premier à l'esprit, c'est d'écrire:

Dim Obj as Class1
Dim CopyOfObj as Class1
'.....
Set CopyOfObj = Obj

En fait, ce que j'ai, c'est 2 variables qui pointent vers le même objet.
Donc si je modifie CopyOfObj, Obj est modifié aussi.
Or, ce n'est pas ce que je veux !!

Est-il possible d'écrire une fonction qui crée un *nouvel* objet ayant le meme contenu que le premier objet ? (donc ayant les
propriétés)

Exemple: Set CopyOfObj = CreateObjectCopy(Obj)

Merci

Pascal B.

6 réponses

1 2
Avatar
Pascal B.
Merci Patrick pour toute ces précisions.

Finalement, j'ai opté la solution proposée par Quasimodo suggérant de créer une méthode propre à l'objet.

Quand le problème c'était posé pour mon application, mon idée première était de généraliser le procédure et ainsi pouvoir cloner
(copier) n'importe quel objet.
C'est alors que des milliers de questions se sont bousculées dans mon petit cerveau.
Voilà pourquoi j'ai posé la question sur ce forum (qui releve un peu le niveau).

Pascal B.

"Patrick Philippot" wrote in message news:
| Pascal B. wrote:
| > MAIS il y a un MAIS:
| > Il faut que l'objet soit PUBLIC et PERSISTABLE.
|
| Bonjour,
|
| En technologie objet, quand on parle de copie, il y a 2 types possibles:
| shallow copy (ou "bitwise copy") et deep copy. Une "shallow copy" est
| une copie membre à membre des propriétés de l'objet source vers l'objet
| cible. Mais le problème c'est qu'une de ces propriétés peut être elle
| même une référence à un autre objet (propriété de type object). Une
| shallow copy ne va donc pas produire un clone indépendant puisqu'il est
| possible que dans chacune des copies, une des propriétés au moins pointe
| sur un même objet.
|
| Une "deep copy" tiendrait normalement compte de cela en créant une
| nouvelle instance de l'objet pointé par une des propriétés. Mais le
| phénomène peut se répéter à l'infini, l'objet pointé par une des
| propriétés pouvant lui-même avoir une propriété de type objet. Pour ces
| raisons, réaliser une "deep copy" est souvent très compliqué et
| difficilement automatisable en VB6 (en VB .Net, avec les mécanismes de
| réflexion, on pourrait l'envisager).
|
| La seule méthode sûre en VB6 pour réaliser une shallow copy est une
| copie explicite membre à membre. En effet, se contenter de copier un
| buffer en mémoire à partir d'une adresse donnée est une opération qui
| suppose
|
| 1) une connaissance intime de l'organisation de l'objet en mémoire.
| 2) que le bloc d'instance en mémoire (le bloc mémoire qui contient les
| données de l'objet) est continu, ce sur quoi vous n'avez aucune
| garantie.
|
| Une telle opération est donc vouée à l'échec dans la plupart des cas.
|
| La méthode que vous décrivez, qui passe par l'intermédiaire d'un
| Property Bag ne fonctionne en effet qu'avec les objets COM et ce sera de
| toutes façons une "shallow copy".
|
| --
| Patrick Philippot - Microsoft MVP
| MainSoft Consulting Services
| www.mainsoft.fr
|
|
Avatar
Patrick Philippot
ng wrote:
Sinon la longueur d'un objet est de 4 octets (dword) car la variable
contient en fait seulement l'adresse de l'objet (donc sur un long).



Exact mais ça n'est pas ce qui était recherché en vue d'une copie. Pour
copier une instance, il faudrait connaître la longueur du bloc
d'instance (le bloc mémoire qui contient les données d'instance de
l'objet et qui est pointé par cette référence). Et encore, comme je l'ai
expliqué, ça ne suffirait pas.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
ng
Oui en effet mon code se contentait de copier le pointeur, erreur stupide :)

--
Nicolas G.
FAQ VB : http://faq.vb.free.fr
API Guide : http://www.allapi.net
Google Groups : http://groups.google.fr/
MZ-Tools : http://www.mztools.com/

Patrick Philippot wrote:
ng wrote:
Sinon la longueur d'un objet est de 4 octets (dword) car la variable
contient en fait seulement l'adresse de l'objet (donc sur un long).



Exact mais ça n'est pas ce qui était recherché en vue d'une copie.
Pour copier une instance, il faudrait connaître la longueur du bloc
d'instance (le bloc mémoire qui contient les données d'instance de
l'objet et qui est pointé par cette référence). Et encore, comme je
l'ai expliqué, ça ne suffirait pas.


Avatar
YannX
"ng" a écrit dans le message de
news:%
Oui en effet mon code se contentait de copier le pointeur, erreur stupide


:)

--
Nicolas G.
FAQ VB : http://faq.vb.free.fr
API Guide : http://www.allapi.net
Google Groups : http://groups.google.fr/
MZ-Tools : http://www.mztools.com/

Patrick Philippot wrote:
> ng wrote:
>> Sinon la longueur d'un objet est de 4 octets (dword) car la variable
>> contient en fait seulement l'adresse de l'objet (donc sur un long).
>
> Exact mais ça n'est pas ce qui était recherché en vue d'une copie.
> Pour copier une instance, il faudrait connaître la longueur du bloc
> d'instance (le bloc mémoire qui contient les données d'instance de
> l'objet et qui est pointé par cette référence). Et encore, comme je
> l'ai expliqué, ça ne suffirait pas.



En première approximation, la réponse serait l'équivalent du sizeof du C
!
(je n'ai pas la pratique des fonctions de Basic....lol)
Mais si un objet utilise comme facette un autre objet, OUT !!!

Donc, pour copier un objet = reste deux solutions à étudier !
1°/ écrire la fonction de copie programmée
(une méthode spécifique de plus, dommage qu'on ne puisse surcharger
le = !)
2°/ écrire un = sur le type Object, et fairte comme avec la collection des
champs d'un RecordSet,
cela doit bien exister quelque part dans VB....cette collection (sans
oublier qu'il peut s'agir d'objets...)
@+
Avatar
Pascal B.
Salut,

"YannX" wrote:

| 2°/ écrire un = sur le type Object, et fairte comme avec la collection des
| champs d'un RecordSet,
| cela doit bien exister quelque part dans VB....cette collection (sans
| oublier qu'il peut s'agir d'objets...)

Je pense qu'il existe un certain "TypeLib" qui permet retrouver tous les membres (propriétés) d'un objet.
Ainsi pour le *nouvel* objet, on copirait, en fait, les propriétés une par une.

Mais comme le disais Patrik,
reste le problème des propiétés qui retournent elles-même un nouvelle objet:
-Soit on fait aussi une copie de membre-à-membre sur celui-ci (avec un "TypeLib")
-Soit on fait une référence sur le même objet (avec un Set)

Le choix dépendra du traitement à effectuer.
Il y aura alors un paramètre supplèmentaire à la fonction qui définira le niveau de copie.

Mais ce "TypeLib" existe-il?
Fonctionne-t-il bien comme je le pense ?

Pascal B.
Avatar
Patrick Philippot
Pascal B. wrote:
Mais ce "TypeLib" existe-il?



Bonjour,

C'est la bonne question car en fait, une typelib n'a rien d'obligatoire.
Les typelib existent toujours pour les objets générés par VB6 car en
fait, celui-ci se limite à des objets COM de type Automation. Ces objets
font voir "logiquement" au client un ensemble de propriétés, méthodes et
événements mais ce n'est qu'une "illusion" car en réalité, un objet COM
, à bas niveau, n'expose que des méthodes (les méthodes des interfaces
COM qu'il supporte et dont l'adresse en mémoire est en fait le seul
point d'accès physique à l'objet).

Un grand nombre d'objets COM n'ont donc pas de typelib associée mais il
est vrai qu'en général, ils ne sont pas utilisés directement depuis un
programme client VB. Mais vous n'en aurez jamais la certitude. Et vous
n'aurez pas non plus la certitude que tous les objets référencés par des
propriétés d'autres objets (en cascade) sont des objets COM de type
automation.

De plus, déduire dynamiquement de la typelib l'ensemble des propriétés
d'un objet n'est pas une tâche évidente en VB6. Il y a un article ici
qui décrit comment procéder:
http://msdn.microsoft.com/msdnmag/issues/1200/TypeLib/default.aspx .

Je le répète, tenter d'implémenter une "deep copy" avec un outil comme
VB6 et une technologie comme le COM est très aventureux. Nous sommes
loin d'un contexte comme celui de .Net où ce genre d'opérations est de
loin plus facile à mettre en oeuvre.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
1 2