SOS polymorphisme avec VC++

CanardLeBarbare Messages postés 19 Date d'inscription lundi 13 janvier 2003 Statut Membre Dernière intervention 7 mars 2004 - 10 juin 2003 à 22:01
CanardLeBarbare Messages postés 19 Date d'inscription lundi 13 janvier 2003 Statut Membre Dernière intervention 7 mars 2004 - 11 juin 2003 à 18:27
g un probleme.

j ai une classe CPersonne. Une autre classe CAmi qui est une sous classe de CPersonne.

dans CAmi je redefinie la methodes Afficher() de CPersonne
et je met virtual devant sa declaration.

mon BUT: stocker dans un pointeur de type CPersonne , une instance de la classe CAmi, puis lorsque j appelle la methode Afficher() c est la methode de CAmi qui se declenche.

bon voila ce que je fais et qui marche tres bien:
------------------------------------------------------

CPersonne * pPersonne = new CPersonne;
CAmi Ami;

//j initialise l ami:4 parametres(alors que la personne en a 3)
Ami.Init("lebarbare", "canard", 21 ,"bon pote");

//puis je le copie dans la personne:
memcpy(pPersonne,&Ami,sizeof(Ami));

//maintenant si je fais Afficher():
pPersonne->Afficher();

//VOILA CE QUI SORT:
nom=lebarbare
prenom=canard
age=21
c est un bon pote :)

------------------------------------------------------
Donc ça c ce que je veux.

MAIS ça ce n est qu un test (qui fonctionne), en réalité j'ai fait un template de collection (comme en VB), qui doit contenir des objets du type précisée et des classes en découlant (des copies pas juste des pointeurs sur ces objets).

le truc c ke je fais exactement comme ce que g fait en haut...
Mais lorsque je fais Afficher() là il m affiche effectivement CAmi::Afficher() , c est a dire nom, prenom, age et niveau d'amitié (alors que CPersonne::Afficher() ne renvoit que nom, prenom, et age) MAIS NIVEAU D AMITIE EST INCOHERENT!!!
mais attention la valeur n est pas non initialisé c juste pas du tout ce que j ai mis dans init()....

voila j espere que g été compréhensible, aidez moi siouplait il s'agit d un des prog que je dois présenter pour mon BTS info/developpeur le 18 juin :(

2 réponses

theneoiceman Messages postés 78 Date d'inscription lundi 14 avril 2003 Statut Membre Dernière intervention 23 avril 2010
11 juin 2003 à 14:23
essayons de trouver l'explication tu veux bien ?
tu créés ta classe CPersonne avec une méthode afficher dedans et d'autres trucs du genre ok ?
ta méthode afficher est ecrite ainsi je pense :
virtual void afficher(...)
{
...nom...prenom...age;
}

on continue...
tu te créés une sous-classe CAmi qui redéfinit cette méthode de cette manière :

class CAmi : public CPersonne
{
// déclaration de ta variable contenant le niveau d'amitié.

puis encore ta fonction afficher :
void afficher()
{
... // tu affiches tes 4 variables
}
}

en gros c'est ca si j'ai bien compris...

La question que je me pose est : pourquoi tu déclares une instance de ta classe CPersonne et que ensuite tu déclares une instance de ta classe CAmi pour ensuite réécrire le contenu de ta classe CAmi dans ta classe CPersonne avec une memcpy(...) ?
Ca sert a rien tu te compliques la vie !!!
Deja une les fonctions virtuelles ne fonctionnent bien que avec les pointeurs donc faut refaire ta delaration de CAmi...
Ensuite tu n'as pas besoin de déclarer CPersonne et de lui coller les données de CAmi...

Tout ce que tu as a faire c'est ça :
pour tes classes :
- CPersonne :
{
// declare tes 3 variables : nom,prenom,age ici en public
// OU protected

virtual void afficher()
{
... // tu ne peux afficher que les 3 variables déclarées ci-dessus
};
}

- CAmi :
{
//declare ta variable contenant le commentaire

void afficher()
{
... // tu affiches les variables que tu veux
}
}

dans ton main ca donne :
{
CAmi * ami = new CAmi();

ami->init(...);

ami->afficher();
}

là ca devrait marcher sans pb...
il y a une autre méthode un peu plus complexe mais plus précise encore, je te la dirai si tu me la demandes.

Le fait que tu vois que ta variable de niveau d'amitié ne s'affiche pas dans ton programme vient du fait que dans ta classe CPersonne, la variable contenant ceci n'existe pas ! elle n'existe que dans la classe fille CAmi ! Si elle n'existe pas, elle n'est pas initialisée (malgré ton memcpy) et donc t'obtiens un vieux resultat en voulant afficher quelque chose qui n'existe pas !

Si tu veux plus d'explications préviens moi j'essaierai d'être plus clair !
;-)
0
CanardLeBarbare Messages postés 19 Date d'inscription lundi 13 janvier 2003 Statut Membre Dernière intervention 7 mars 2004
11 juin 2003 à 18:27
bon c sympa mais ça ne résout pas mon problem ta solution, g du mal expliqué :P

bon alors le principe du template c est de stocker des objets du type specifié. (donc si c CCollection<CPersonne> je veux qu il stocke une personne et pas juste un pointeur sur une personne dans le cas ou la personne ajouté serait une variables temporaires...si je dis pas de betise lorsque la personne serait detruite, il devrait toujours y avoir le meme objet dans la collection, d ou mon utilisation de memcpy()).

bon je crois que mon probleme viens de memcpy(), explications:

la version qui marche:
-------------------------
void main()
{
CPersonne * pPerso = new CPersonne();
CAmi * pAmi = new CAmi();

pAmi->Initialiser(...);

memcpy(pPerso,pAmi,sizeof(*pAmi));

delete pAmi;

pPerso->Afficher();
}

//ça ça fonctionne tres bien!!!!! il m affiche les 4 variables de CAmi!

maintenant la version qui marche pas:
-------------------------------------------

dans mon template cette partie du code s'effectue dans CCellule::Initialiser()

template<T> CCellule<T>::Initialiser(T * pObjetSource)
{ pObjetCible new T; //ici T CPersonne

memcpy(pObjetCible,pObjetSource,sizeof(*pObjetSOurce));
...
}

//et qd ensuite je lui demande de m afficher :
pObjetCible->Afficher();
//il m'affiche CAmi::Afficher() MAIS la 4ème variable est fausse!

le pire c est que lorsque que je fais afficher juste avant le memcpy:

pObjetSource->Afficher();

là toutes les valeurs sont justes (les 4), il m'affiche bien une instance de CAmi.

du coup je sais pas trop quoi faire...

a tout hasard: j utilise des CString dans ma classe CPersonne

voila voila,

docteur c grave?
0
Rejoignez-nous