[C++] Destructeur ? Comprends pas..

Destructeur ? Comprends pas.. [C++] - C++ - Programmation

Marsh Posté le 20-03-2008 à 21:38:24    

Salut à tous,
 
Je réalise en ce moment un casse brique pour l'IUT et j'ai un probleme avec mes briques. En effet j'ai créé un constructeur brique qui me permet de creer un mur de briques (j'en ai mis que 2 pour le moment tant que j'ai pas réglé mon problème) et j'aimerais pouvoir détruire l'instance de brique concernée dès que la balle rentre en collision avec elle.
 
Donc pour la collision le changement de trajectoire tout va bien mais le seul truc que j'arrive a faire c'est caller la brique en dehors de la zone de jeu (et de vue) pour pas qu'elle m'embête.
 
J'aimerais détruire l'instance sachant qu'il y aura autant d'instance de la classe que de briques.
J'ai cherché un peu mais je comprends pas comment détruire une instance statique, j'ai juste trouvé pour les pointeurs seulement.
 
Je vous met le bout du code ou j'aimerais insérer le destructeur :
 

Code :
  1. if( check_collision( maBalle.get_positionBalle(), maBrique.get_positionBrique()) == true )
  2.             {
  3.                 maBalle.modif_yVel();
  4.                 //Destructeur ici
  5.             }

Reply

Marsh Posté le 20-03-2008 à 21:38:24   

Reply

Marsh Posté le 20-03-2008 à 21:40:54    

ben tu crees avec new, et tu detruis avec delete

Reply

Marsh Posté le 20-03-2008 à 21:41:39    

Mes instances sont statiques j'utilise pas de pointeurs

Reply

Marsh Posté le 20-03-2008 à 21:44:53    

Tiens, lis ceci, il y a un chapitre sur les constructeurs/destructeurs : http://www.cplusplus.com/doc/tutorial/classes.html

 

Un constructeur n'est appele que dans deux cas : tu definis un objet local, ou tu instancies avec new.

 

Un destructeur, de maniere similaire, n'est appele que dans deux cas : tu sors de la portee de l'objet local (donc il est automatiquement detruit), ou tu appelles l'operateur delete.

 

Donc si tu utilises des objets locaux, le seul moyen de les detruire, c'est de sortir du scope. [:petrus75]
Apres, tu peux toujours ajouter un flag qui indique que l'objet est actif ou non.


Message édité par Elmoricq le 20-03-2008 à 21:46:07
Reply

Marsh Posté le 20-03-2008 à 21:45:00    

Salut,

 

Il te faut ajouter un attribut précisant si elle doit, ou non, être affichée. Tu ne le dessines que s'il le faut, ce qui n'est pas le cas lorsqu'elle est cassée.


Message édité par IrmatDen le 20-03-2008 à 21:45:13
Reply

Marsh Posté le 20-03-2008 à 21:49:41    

J'arrive a ne plus l'afficher mais il reste toujours la en etant invisible en fait et la balle continue a ricocher dessus.

Reply

Marsh Posté le 20-03-2008 à 22:42:55    

Et donc, tu en déduis? Tu peux aussi relire la réponse d'Elmoricq si t'as besoin d'un indice.

Reply

Marsh Posté le 20-03-2008 à 22:59:04    

Ah c'est bon j'ai réussi grace a toi irmat :p j'ai mis comme condition dans le if de la collision que il fallait que maBrique.cassee soit false pour que ca check par contre faut que je trouve comment la faire disparaitre de l'affichage maintenant.

Reply

Marsh Posté le 21-03-2008 à 00:44:48    

Je fais apparaitre les brique grace a la SDL et Blitsurface plus précisement. Une fois qu'elles sont incrustées j'ai l'impression qu'il est impossible de les enlever que c'est incrusté dans l'image. J'ai donc essayé de mettre par dessus une brique couleur de fond sans succès.

Reply

Marsh Posté le 21-03-2008 à 14:17:20    

Normalement, la brique devrait s'afficher elle-meme, en appelant sa propre fonction d'affichage.
 
Idealement, tu devrais avoir n objets sur ton ecran : une balle, des briques,  un plateau, pourquoi pas des bonus... et meme les briques, balles, plateaux peuvent etre differents.
Le moyen le plus chouette de gerer ca, c'est d'avoir une classe interface generique (http://www.cplusplus.com/doc/tutorial/polymorphism.html , lire "virtual members" ), avec la descriptions de quelques fonctions de base : une fonction affichage(), un flag indiquant si l'objet est actif ou non, et une ou deux choses communes a tous tes objets, a toi d'y mettre le necessaire.
Ensuite, tu auras des objets qui heriteront de cette classe : brique, balle, plateau, etc. Chacune de ces classes implementeront leur propre fonction d'affichage, et tout ce qu'il y a de propre a ces objets.
 
Et, enfin, la fonction affichage de tes objets devra debuter par un test : si le flag "actif" est a false, alors ne pas afficher.
 
L'avantage de faire comme ca ? C'est le suivant : tu peux te contenter d'un vector<ta classe generique>, contenant tous tes objets. Pour les fonctions generales d'affichage, il te suffit juste de parcourir ton vector<> et d'appeler la fonction de la classe. Grace au polymorphisme (cf. le lien ci-dessus), la fonction d'affichage propre a l'objet fils sera appelee. Et comme chacun de tes objets gerera son propre flag "actif" (meme pour la bille ca peut etre utile, si tu souhaites ajouter une option qui donne un multiball ;) ), tu sera tranquille.
 
Classe generique (definition des fonctions de base virtuelles)
|         |        |     |_ Balle
|         |       |_ Brique
|         |_ Plateau
|_ (eventuellement) option
 
 
Pour SDL j'en sais rien, je ne connais pas.


Message édité par Elmoricq le 21-03-2008 à 14:18:24
Reply

Marsh Posté le 21-03-2008 à 14:17:20   

Reply

Marsh Posté le 22-03-2008 à 14:49:59    

Juste histoire de jouer les aigris, et parce que Taz n'est pas encore passé lancer des vannes, je n'aime pas du tout la méthode des classes de base abstraites avec des virtuelles partout.
 
Ici on fait du C++, pas du Java. Si à certains endroits tu peux avec des containers genre vector<Brique> et vector<Balle> c'est mieux que des vector<Object*> ou Object est du type abstrait.
 
Pkoi ?
 
- Pas d'appels virtuels
- Pas de vfptr dans tes objets (gains de mémoire)
- Quand tu cherches une brique, tu peux te contenter de chercher dans le vector<Brique>, pas besoin de chercher dans un grand vector<Object*>. Et tu gagnes un niveau d'indirection.
- Pas besoin de faire les new et les delete à la main. vector<> s'en charge.
 
edit : typo


Message édité par jesus_christ le 22-03-2008 à 14:50:38
Reply

Marsh Posté le 22-03-2008 à 16:07:51    

en fait, c'est moi qui suis sensé lancer des vannes qd Taz ets pas là. MErci de aps me piquer mon travail :o ;)

Reply

Marsh Posté le 22-03-2008 à 18:31:48    

au temps pour moi, je savais pas que Taz avait un remplaçant.
J'ai lu d'autres de tes posts, t'as un stype plus léger, ça fait du bien ;)

Reply

Marsh Posté le 22-03-2008 à 19:06:11    

jesus_christ a écrit :

au temps pour moi, je savais pas que Taz avait un remplaçant.
J'ai lu d'autres de tes posts, t'as un stype plus léger, ça fait du bien ;)


 
Bah t'as pas tout lu alors  :whistle:

Reply

Marsh Posté le 23-03-2008 à 18:56:50    

Yo,
Juste pour repondre rapidement : les arguments sur la performance et sur la consommation memoire, dans le cas d'un casse-brique ou de bon nombre de programmes pour lesquels l'argument de la maintenabilite devrait primer, ne devraient pas compter je trouve (il y a evidemment des cas particuliers ou, pour le coup, il s'agit d'arguments vitaux, mais pas ici a mon avis).
 
Par contre, les deux points sur la gestion du new/delete vs. gestion auto., et celui de la recherche d'un objet precis, sont effectivement de bons arguments. [:dawa]
Le new/delete n'est pas tellement un probleme quand meme, c'est assez facile a gerer avec une conception claire, par contre perdre du temps a chercher un objet specifique dans un vector<Object*> c'est quand meme tres con (et tres sale :o), j'avoue que j'avais pas pense a cet aspect. [:romf]


Message édité par Elmoricq le 23-03-2008 à 18:57:55
Reply

Marsh Posté le 23-03-2008 à 20:52:09    

Pour moi il faut toujours garder un code propre et optimisé, sans pour autant s'acharner pour des gains minables. Mais penser au perfs dès le commencement (et ici le choix de la représentation et si fondamental qu'il serait dur à changer + tard) permet de produire des bons softs et de prendre des bonnes habitudes.
 
Knuth a dit qu'une optimisation précode est la racine de tous les maux.
C'était dans les années 70 et il parlait du code assembleur. Pour le C++ Stroustrup et Alexendrescu on rectifié en disant en gros que "ouais, mais du code écrit sans aucune notion de perf était la feuille de tous les problèmes" (jeu de mots avec "root of the evil" ).
 
J'aimerais que les gens oublient un peu Knuth...

Message cité 1 fois
Message édité par jesus_christ le 23-03-2008 à 20:57:00
Reply

Marsh Posté le 23-03-2008 à 21:23:25    

Ouais enfin moi j'interprete les propos que tu cites comme un addendum a ceux de Knuth : "l'optimisation precoce c'est le mal, on est d'accord, mais quand meme, ca veut pas dire qu'il ne faut utiliser que des algos en O^n, hein [:dawa]"
 
Bien sur qu'il faut se demander, quand on rencontre une solution qui semble bancale au niveau des perfs, s'il n'y a pas un meilleur moyen. Pour moi ca fait meme partie de l'amelioration de la conception du programme.
Mais de la a bannir les classes virtuelles parce que ca bouffe quelques bytes de plus (pour cette raison-la seulement, apres au niveau conceptuel, on peut les bannir pour d'autres raisons), y a quand meme un ravin je pense.  
 
(encore une fois, j'exclue evidemment les programmes pour lesquels ces considerations sont necessaires, mais ils sont rares)


Message édité par Elmoricq le 23-03-2008 à 21:25:51
Reply

Marsh Posté le 24-03-2008 à 10:44:43    

jesus_christ a écrit :

Knuth a dit qu'une optimisation précode est la racine de tous les maux.
C'était dans les années 70 et il parlait du code assembleur. Pour le C++ Stroustrup et Alexendrescu on rectifié en disant en gros que "ouais, mais du code écrit sans aucune notion de perf était la feuille de tous les problèmes" (jeu de mots avec "root of the evil" ).
 
J'aimerais que les gens oublient un peu Knuth...


Oui, mais c'est moins casse-gueule de rendre rapide un code qui fonctionne (a coup de non-reg), que de deboguer un code deja optimise :D
Le seul cas ou l'acceleration de ton code peu se reveler tres problematique, c'est si la version lente du code utilise des algos exponentiels (ce qui ne devrait jamais etre le cas - a mon avis, c'est ca qu'ont voulu dire Stroustrup et Alexendrescu.
 
On pourrait toujours me repondre que dans ce cas, il vaut mieux ecrire du code rapide des le depart, plutot que de faire ca en deux temps. Helas, le plus souvent, on n'a pas idee de la ou va se trouver le goulet d'etranglement, et le risque de s'acharner pour des gains minables est grand tant qu'on n'a pas encore realise le moindre profiling.
 
Quant a l'histoire des vectors d'objets a la place des vectors de pointeurs abstraits, je pense que c'est precisement un cas de gain minable. Je ne pense pas que le jeu de casse-briques realise ici traite plus d'une cinquantaine de briques a chaque frame, alors, pointeur ou pas pointeur... :D

Reply

Marsh Posté le 24-03-2008 à 13:19:32    

bien sûr que dans le cas de son casse brique le gain de ram et de perf sera minable, même négligeable, et même s'il avait codé en Basic ça serait qd même fluide.
 
Mais il est en IUT, c'est donc un exercice, et je lui conseille donc de prendre de bonnes habitudes, parmis lesquels ne pas commencer à coder en C++ avec des classes abstraites et des méthodes virtuelles partout. Pas de problème pour un exo d'IUT, mais le jour où il faudra développer un vrai softs dans des conditions réelles, avec des vrais problèmes de mémoire et de perfs ça peut faire la différence.
 
Maintenant il vaut mieux un softs fonctionnel avec des algos ayant un complexité la + faible possible qu'un truc optimisé au bit près qui ne marche pas et qui est pas maintenable, je suis d'accord.
 
Je dis juste que le style de conception d'Elmoricq ne coresspond pas au paradigme (oui je case un mot compliqué) du C++. Par contre en Java je trouverais ça assez élégant.
 
Si vous voulez un exemple concret, comparer l'implémentation du foncteur universel dans Loki et dans boost (boost::function).
Dans loki il y a 3 niveaux d'indirection et des virtuelles pures partout. Dans boost, rien de virtuel. Le mec qui a écrit Loki* n'a pas compris que dans les lib C++ (et uniquement C++) les utilisateurs attendent un minimum d'optim et n'aime pas voir des appels virtuels là où il ne sont pas nécessaires.
Maintenant encore coder pour boost et coder pour un exo d'IUT, il y a un fossé.
 
* : paradoxalement, c'est Alexendrescu ce type.

Reply

Marsh Posté le 24-03-2008 à 14:18:54    

Loki::function c'ets vieux et je pense qu'il a du en revenir ^^

Reply

Marsh Posté le 24-03-2008 à 14:22:42    

moi j'utilise à gogo les conteneurs spéciaux de boost et j'en suis très content. Comme toujours faut savoir ce qu'on veux. C'est pas trop la peine de se fatiguer à vivre sans virtual si au final ça n'apporte rien de flagrant.

Reply

Marsh Posté le 24-03-2008 à 14:50:24    

merci pour le lien, je connaissais pas !
par contre dommage qu'ils ait pas enlevé un niveau d'indirection dans les itérateurs, ça me gonfle souvent d'écrire ( *it )->f();
 
"se fatiguer à vivre sans virtual si au final ça n'apporte rien de flagrant"
Complètement d'accord, mais le réciproque est vraie aussi, ne pas systématiquement mettre du virtual qd on peut facilement s'en passer.

Reply

Marsh Posté le 24-03-2008 à 15:22:39    

justement si

Code :
  1. typedef boost::ptr_vector<animal>  ptr_vec;
  2. ptr_vec vec;
  3. ptr_vec::iterator i = vec.begin();
  4. i->eat(); // no indirection needed


Message édité par Taz le 24-03-2008 à 15:22:53
Reply

Marsh Posté le 24-03-2008 à 20:58:12    

dans boost::ptr_map l'indirection est encore là, mais boost::ptr_vector a l'air pas mal. Je m'en servirai peut-être au boulot maintenant que je connais. merci !

Reply

Marsh Posté le 24-03-2008 à 22:02:43    

bah dans ptr_map, c'est pas obligatoire d'avoir l'indirection ???

Reply

Marsh Posté le 25-03-2008 à 11:25:37    

voir la doc. Si. Mais l'interface est double.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed