Se connecter / S'enregistrer
Votre question
Résolu

[C++] Classe abstraite : faire choisir automatiquement le "bon" operator=

Tags :
  • C++
  • classe
  • héritage
  • surcharge opérateur
  • polymorphisme
  • Programmation
Dernière réponse : dans Programmation
30 Mai 2012 13:09:34

Bonjour,

Voici mon souci :
J'ai une classe abstraite A qui contient des méthodes virtuelles pures, et des classes dérivées de A qui sont A1, A2, etc...
J'ai par aileurs une classe B, qui contient un pointeur sur A (A *pa) ainsi que d'autres membres... l'idée est que pA permet d'appeler des fonctions des classes dérivées de A en fonction du contexte dans lequel on utilise l'objet de type B.

Mon souci est au niveau du constructeur de recopie de B (et de l'operateur= ) :
Comment faire pour que l'instruction (présente dans l'operator= de la classe B, et dans le constructeur de recopie)
  1. *(this->pA) = *(rhs.pa)
choisisse l'operator= de la classe dérivée adéquate ? Car j'ai l'impression qu'il veut à tout prix appeler l'operator= de A.

Avec les méthodes renvoyant un type fixé à l'avance (genre double fonction(x)) il suffit de les déclarer comme virtuelles pures dans la classe abstraite et de les définir dans chaque classe dérivée ce que j'utilise bcp.
Mais là, si je mets l'operator= en virtuel pur dans la classe abstraite, il doit renvoyer une référence de type A ce qui m'empêche de définir operator= dans A1, A2 etc... puisque le type renvoyé diffère à chaque fois...
Alors que moi je veux qu'il renvoie une référence sur A1, A2 ou A3 etc... suivant le contexte.

De plus le nombre de classe dérivée A1, ... An n'est pas encore défini, donc je ne peux pas me contenter d'un "case" sur le type désiré... il faudrait que ça se fasse automatiquement en fonction de où je fais pointer pA dans le constructeur de B (s'il pointe sur un A1, alors on appelle l'opérator= de A1, s'il pointe sur un A2, alors on appelle l'opérator= de A2 etc...)

Y a t il une façon de régler ce problème ?

Merci à vous !

Autres pages sur : classe abstraite choisir automatiquement bon operator

31 Mai 2012 17:53:59

Re !

Il semble qu'il existe une solution à mon pb, il s'agit de créer une fonction pour "cloner" (clone pattern) : http://www.cplusplus.com/forum/articles/18757/
J'ai testé, ça marche bien (ouff!!!) ! En revanche, je trouve que la méthode n'est pas très "propre" dans le sens où c'est une fonction qui va allouer la mémoire dynamiquement et que ce n'est pas elle qui va détruire l'objet ainsi créé (bon ok, il y a le destructeur qui peut tester l'existence du pointeur et faire un delete ... mais imaginons que qqun fasse un usage malsaint de cette fonction clone() ... ).
Si je comprends bien, on ne peut pas faire ça en static puisque chaque appel de cette fonction occuperait de la mémoire programme déterminée lors de la compilation (je ne dis pas de conneries ?) ... je ne peux pas non plus faire ça en renvoyant une variable interne à la fonction clone() car celle-ci serait détruite après le return de la fonction vu que ça serait fait sur la pile.

La solution de l'operator= ne peut-elle tout de même pas être utilisée (je trouve ça moche de devoir faire this->pointeur = rhs.clone() au lieu de *(this->pointeur) =*(rhs.pointeur) )

Bon en attendant, je reste sur le "clone pattern" ...

A suivre ...
m
0
l

Meilleure solution

a b L Programmation
2 Juin 2012 20:00:05

Salut,
clone est un design pattern classique (tu peux l'appeler cloneNew si tu veux être plus explicite).

Après ton clone peut aussi être simplement: A clone(); en créant une instance de A sur la pile et pas sur le tas
c'est-à-dire que ça retourne une copie de l'objet que tu crées temporairement dans la méthode (sans utiliser de pointeur).
L'inconvénient est que tout est fait dans la pile (le contexte de la méthode), et donc, ce qui est retourné, c'est une copie de objet temporaire, et qui dit copie, dit appel au constructeur par recopie. Donc, pour ça, il faut faire attention à 2 choses:
- bien faire tous les constructeurs par recopie (attention au bugs sur les recopies partielles :)  )
- se dire que l'objet est au final copié 2 fois (si l'objet est gros, ça peut prendre de la mémoire)

le problème de l'opérateur = est que tu l'appliques sur l'objet pA qui n'est pas typé s'il est à NULL. Tu peux pas changer de méthode selon le type du paramètre (je mets de côté les techniques complexes de template qui finissent toujours par poser d'autres problèmes). Si cela était possible, il faudrait prévoir la copie d'un objet A1 sur un objet A2 (ce qui peut être le cas si pA est déjà affecté à un objet de classe A1 ou A2).
Bref, le clone est la seule solution viable.
partage
3 Juin 2012 12:41:26

Ok

Merci pour la confirmation ! Tout semble bien fonctionner de cette façon.
m
0
l
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS