c'est pas compliqué à comprendre.
si tu fais:
class Patate
{
public:
int truc, machin, bidule....
};
main()
{
fonction1();
}
fonction1()
{
Patate petitepatate;
}
"petitepatate" n'existera plus à la fin de fonction1.
de retour dans le "main" d'une part, tu n'as pas moyen d'atteindre quelque chose qui viens de "fonction1", et d'autres part si tu arriverais à le faire (j'anticipte le truc dégueulasse que je vais expliquer à la fin), tu atteinderai un truc qui est indéfini, logiquement inexistant (mais pourtant touchable).
pour "créer" quelque chose qui survit autant que tu veux, il faut le créer dynamiquement avec un new (et se démerder pour ne pas le perdre).
donc par exemple:
Patate *fonction2()
{
Patate *ptte=new Patate; // cette Patate vivra jusqu'a ce que on la "delete"
ptte->OnLaLave();
return ptte;
}
main()
{
Patate *patatevivante;
patatevivante=fonction2();
for( .... on boucle .... par exemple sur des pressions de touche )
{
si touche 'P':
patatevivante->OnLaPèle();
si touche 'C'
patatevivante->OnLaCuit();
si touche 'B'
// pouBelle
delete patatevivante;
}
}
Si tu prends les 2 pointeurs, ils sont temporaires, local à chaque fonction, le pointeur "ptte" est local à "fonction2", "lui-même" il saute à la fin de la fonction, mais pas l'objet "Patate" qu'il pointait par son doigt vengeur.
Et lorsque "fonction2" retourne elle redonne l'adresse de l'objet Patate crée au "main" qui la maintiendra via sont pointeur "patatevivante".
et lorsque tu appuies sur B là l'objet Patate est réllement supprimmé entre "", mais attention le pointeur pointe toujours sur l'ancien emplacement mémoire de la Patate.
Même si la Patate n'a plus cours, on peut toujours la pointer du doigt.
tu peux donc faire l'horrible et punissable erreur (par une flagellation en place publique) de bricoler le cadavre de la Patate en tentant de la triturer. (la nécrophilie c'est le mal)
donc la chose à ne pas faire ce serait de se retrouver avec ça:
si touche B:
delete patatevivante;
patatevivante->longueur=patatevivante->hauteur*16/9;
//(pour mettre la patate au format cinémascope)
et là si tu le fais, tu verras tout une équipe de rugby se ruer sur toi pour te plaquer au sol afin de te punir.
et prends garde: plus l'équipe mets du temps à venir, plus forte sera la pression.
-donc- pour ne pas faire ça, on pourrait changer main ou tout autre fonction (qui contiendrait la boucle de réaction aux pression de touches, on n'est pas limité à main) pour avoir quelque chose comme ça:
main()
{
Patate *patatevivante;
patatevivante=fonction2();
while( patatevivante ) // à traduire par "tantque patatevivante est non nulle, et quelque chose différent de 0 est non nul"
{
si touche 'P':
patatevivante->OnLaPèle();
si touche 'C'
patatevivante->OnLaCuit();
si touche 'B'
// pouBelle
delete patatevivante;
patatevivante=NULL; // ou équivalent patatevivante=0;
}
}
là on sait que le pointeur "patatevivante" en étant initialisé à une valeur (donc adresse en fait) connue et ayant comme convention un pointeur qui pointe sur rien (bien que c'est faux il pointe sur l'adresse 0000000), on peut éviter de triturer cette pauvre Patate quit pourrit dans la poubelle (ce qui n'est pas très hygiénique tu m'accorderas).
donc:
tu veux un truc qui vive "tant que tu le décides":
généralement ça fera quelque chose comme:
Patate *doigt_sur_patate=new Patate;
tu veux benner la patate:
delete un_doigt_sur_une_patate;
sachant que "un_doigt_sur_une_patate" est en principe un pointeur sur Patate, donc un "Patate *" quelquechose;
ce n'est pas forcément le même pointeur...
tu peux avoir plusieurs pointeur qui pointent sur le même objet.
donc maintenir à la création ta Patate dans "Doigt1", genre:
Patate *Doigt1=new Patate;
... du code, des appels de fonctions
... du code, des appels de fonctions
Patate *Doigt2;
... du code, appels...
... du code, appels...
Doigt2=Doigt1;
... du code...
delete Doigt2;
là notre Patate originalle sera bien supprimmée.
MAIS: autre cas de flagellation, pas de multiples "delete".
pour chaque "new", son seul et unique "delete".
Donc PAS de:
delete Doigt2;
delete Doigt1;
tout en sachant Doigt2 et Doigt1 doigtent la même Patate.
à toi d'être cohérent dans ta tête.
sinon c'est la peine de mort pour ton programme.
et symétriquement, chose aussi qui te fera brûler en enfer:
(c'était le truc dégueulasse dont je parlais au début)
Patate *fonction3_pas_belle()
{
Patate patate_locale;
....
.... du code
return &patate_locale;
// et oui patate_locale où qu'elle soit, a une adresse,
// les robots chinois du FBI peuvent donc la traquer
// et la pointer du doigt.
}
main()
{
Patate *patate_pourrie;
patate_pourrie=fonction3_pas_belle();
...
...
...
}
voilà donc là, la "patate_locale" de "fonction3_pas_belle" étant locale à la fonction, passera à la benne toute seule en sortant de "fonction3_pas_belle", qui retournera quand même l'adresse mémoire de la défunte et contagieuse Patate.
-----
voilà on a fait le tour, je ne vois pas comment t'expliquer mieux ( à 2h du matin ) le cycle de naissance et de mort d'un objet qu'il soit simple/élémentaire ou compliqué (dans le sens composé par d'autres objets élémentaires ou eux-même compliqués).
après si tu assimilé ça, on pourra par exemple passer aux cours d'éducation sexuelle et comment les objets se reproduisent entre eux (là c'est plus C++, alors que le genre de truc que je t'ai expliqué là ça reste "universel", et quelque chose à maitriser dans ta tête).
pour bien comprendre, relis le tout plusieures fois, et vois comment les choses se complètent, après cela tu seras un padawan de la manipulation objets à travers des pointeurs.
Message édité par bjone le 23-08-2004 à 02:25:16