OVH Cloud OVH Cloud

Caster un objet en un autre objet

14 réponses
Avatar
Korchkidu
Bonjour,

j'ai une classe de base BaseClass et N classe d=E9riv=E9es DerClass1,
DerClass2, etc. Mon programme travaille sur un std::vector<BaseClass*>
et j'ai besoin de pouvoir facilement changer n'importe quel DerClass_i
en n'importe quel autre DerClass_j =E0 l'=E9x=E9cution du programme. Une
solution pourrait =EAtre d'impl=E9menter tous les cast possible mais du
coup, =E0 chaque fois que je rajoute une DerClass, =E7a me fait beaucoup
de boulot en plus car je dois =E9crire tous les cast possibles. Sinon,
je peux isoler la partie qui change d'une DerClass =E0 l'autre et en
faire une classe SubClass pour chaque DerClass. Ensuite, chaque
DerCLass contiendra un pointeur sur le bon SubClass et lorsque je dois
changer le type de DerClass, je d=E9truit le pointeur de SubClass et
j'en recr=E9=E9 un qui =E0 le bon type.

Quelles sont vos suggestions compte-tenu de votre (longue)
exp=E9rience ?

D'avance merci pour votre aide.
K.

4 réponses

1 2
Avatar
James Kanze
On Jul 23, 12:42 pm, Korchkidu wrote:

j'ai une classe de base BaseClass et N classe dérivées
DerClass1, DerClass2, etc. Mon programme travaille sur un
std::vector<BaseClass*> et j'ai besoin de pouvoir facilement
changer n'importe quel DerClass_i en n'importe quel autre
DerClass_j à l'éxécution du programme.



Une première chose : le type d'un objet C++ est determiné pour
toujours lors de sa création. Si tu a réelement besoin d'un
objet qui « change de type », il faut utiliser le modèle
lettre/enveloppe, ou quelque chose de semblable. Mais même
alors, tu pourrais avoir des problèmes à maintenir l'état
lorsque tu change le type.

Sinon, c'est assez simple à faire quelque chose du genre :

BaseClass* tmp = new DerClass_i( *vect[ i ] ) ;
// Constructeur qui recupère l'état...
std::swap( tmp, vect[ i ] ) ;
delete tmp ;

Une solution pourrait
être d'implémenter tous les cast possible



Il n'y a pas (normalement) une conversion DerClass_i en
DerClass_j, et la conversion DerClass_i vers BaseClass risque de
ne pas faire l'affaire.

mais du coup, à chaque fois que je rajoute une DerClass, ça me
fait beaucoup de boulot en plus car je dois écrire tous les
cast possibles. Sinon, je peux isoler la partie qui change
d'une DerClass à l'autre et en faire une classe SubClass pour
chaque DerClass. Ensuite, chaque DerCLass contiendra un
pointeur sur le bon SubClass et lorsque je dois changer le
type de DerClass, je détruit le pointeur de SubClass et j'en
recréé un qui à le bon type.



C'est le modèle Strategy, aussi connu sur le nom de délégation.
Si ça peut marcher, c'est probablement plus simple que les
alternatifs.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Korchkidu
Merci beaucoup pour toutes ces explications. Effectivement, dans mon
cas, le state design pattern fonctionne parfaitement.

K.
Avatar
Michael Doubez
On 27 juil, 19:36, Korchkidu wrote:
Merci beaucoup pour toutes ces explications. Effectivement, dans mon
cas, le state design pattern fonctionne parfaitement.



Pour rebondir sur le post de James Kanze, le pattern s'appelle body/
enveloppe dans la dénomination de James Coplien. Ca vaut le coup
d'aller voir de ce coté car les patterns de Coplien sont plus riches
et ont été exprimés en C++ avec les idiomes associés.

--
Michael
Avatar
James Kanze
On Jul 28, 8:31 am, Michael Doubez wrote:
On 27 juil, 19:36, Korchkidu wrote:



> Merci beaucoup pour toutes ces explications. Effectivement,
> dans mon cas, le state design pattern fonctionne
> parfaitement.



Pour rebondir sur le post de James Kanze, le pattern s'appelle
body/ enveloppe dans la dénomination de James Coplien. Ca vaut
le coup d'aller voir de ce coté car les patterns de Coplien
sont plus riches et ont été exprimés en C++ avec les idiomes
associés.



Ça dépend. À la base, il y a trois modèles, plus ou moins
apparentés :

Stratégie (selon GoF -- j'avais l'habitude de l'appeler
délégation avant, selon le Wikipedia, aussi « policy ») : la
classe principale a un comportement ou un état. Elle n'est
pas polymorphique en elle-même, mais appelle un deuxième
object, lui polymorphique, pour tout ce qui peut varier.

Handle/Body : c'est à peu près la stratégie, sauf que la classe
principale n'a ni de comportement ni d'état ; c'est le
handle qui renvoie tous au body.

Lettre/Enveloppe : c'est un handle/body où le handle, c'est
aussi la classe de base du body. L'intérêt, c'est de ne pas
avoir à dupliquer toutes les déclarations de fonction.

Ce qu'ils ont en commun, c'est que la classe que voit le client
est une classe concrète, et non abstraite, et que s'il a un
sens, on peut même lui donner une sémantique de valeur. Dans le
cas des handle/body ou des lettre/enveloppe, d'ailleurs, je ne
vois pas vraiment l'intérêt de la classe handle ou lettre
autrement ; si on n'a pas une sémantique de valeur pour
l'objet, c'est qu'on l'accède à travers d'un pointeur ou d'une
référence, et je ne vois pas ce que la classe handle ou lettre
apporte par rapport au pointeur ou référence.

Mais si j'ai bien compris le problème, il y a bien un état ou
une partie du comportement commun à toutes les instances. C-à-d
que c'est le modèle stratégie qu'on veut.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
1 2