Des conseils sur mon programme, SVP - C++ - Programmation
Marsh Posté le 02-06-2004 à 18:36:10
ben il faut que mon programme récupère le pointeur sur l'objet créé, pour pouvoir le modifier. bon, je met un bout de code (inventé pour l'occasion) qui aurait pu être dans mon programme principal :
Code :
|
donc ta fonction, dans laquelle tu n'as fais que retirer le renvois de l'adresse de l'objet créé, ne convient pas dans mon cas...
Marsh Posté le 02-06-2004 à 18:41:21
ah non, désolé, je viens de voir ce que tu voulais dire... effectivement, ça pourrais marcher, mais ce serais plutot
Code :
|
il faut que ce soit une référence sur un pointeur, pour que la valeur du pointeur soit réellement modifiée... mais sinon, c pas con... mais dans le fond, ça change pas grand chose... moi je demandais surtout si le principe était correct, pas forcément dans les détails...
Marsh Posté le 02-06-2004 à 18:45:12
Exact, je suis allé un peu vite Comment gères tu le retrait des objets dans ta liste nodes ?
Marsh Posté le 02-06-2004 à 18:46:04
éh, c quoi ça, tu as retiré ton message ? (si c'est possible ?)
Marsh Posté le 02-06-2004 à 18:55:09
alors je donne la classe à partir de laquelle je fais mon objet 'nodes' :
Code :
|
je met pas les définitions de toutes les fonctions, c'est un peu long... le principe de cette classe, c'est qu'elle stocke les objets par un tableau de pointeurs sur les objets. Le tableau est redimensionné si besoin (i.e. un nouveau tableau est créé et l'ancien est copié dedans, puis effacé). C'est pour ça que je stocke tout dedans avec des pointeurs : même si je déplace les poiteurs, l'objet lui même n'est pas déplacé. de plus ça permet de stocké des objets de types différents, mais dérivés d'une même classe de base. enfin, l'histoire du HandleC, c'est une autre classe :
Code :
|
cette classe permet de faire des trucs comme ça :
Code :
|
ensuite, quand l'objet bidon1 sera détruit, ça va appeler le destructeur de l'objet 'HandleC obj' qu'il contient, et donc libérer la mémoire comme il faut, et mettre à jour le tableau de 'nodes'...
Marsh Posté le 02-06-2004 à 19:03:59
Est ce que l'utilisation d'une liste (std::liste<GL_Node*> ) ne permetrait pas deja de simplifier un peu ta classe container. D'ailleurs, si elle n'a qu'une seule instance, tu pourrais en faire un singleton pour le style.
Marsh Posté le 02-06-2004 à 19:04:32
pour répondre à ta question, les retraits sont fais de la manière suivante : l'objet considéré est détruit (avec delete), et le pointeur vers cet objet dans le tableau est remis à NULL. quand on ajoute un objet, le programme cherche le premier pointeur NULL dans le tableau, il créé l'objet (new) et met l'adresse dans le tableau. si tout les pointeurs sont déjà utilisés, le tableau est agrandit.
Marsh Posté le 02-06-2004 à 19:06:29
euh elle n'a pas du tout qu'une seule instance, et le principe de cette classe c'est que quand je détruit un objet dedans, elle ne décale pas tous les autres, histoire de garder le maximum de performances. sinon, je sais pas ce que c'est un singleton... pour info, cette classe est aussi utilisée pour stocker les objets physiques du jeu (description solide de l'objet, pour gérer les collisions), et les effets graphiques (en gros, tout ce qui marche avec des effets de transparence)
Marsh Posté le 02-06-2004 à 19:07:07
Lorsqu'un objet complexe crée à lui seul N objets dans ta liste, comment ca se passe lorsque ton objet complexe doit etre detruit ( comment sont retirés les N objets de la liste constituant ton objet complexe ) ? Gardes tu une trace de ces N objets dans la classe correspondant à ton objet complexe ?
Marsh Posté le 02-06-2004 à 19:08:33
mais en fait, je ne sais pas comment marche std::liste<>. je connaissait std::vector<> mais ça ne corespond pas à ce que je veux, puisque quand on détruit un élément, il décale tous les autres... par exemple, s'il s'agit de la liste de tous les projectiles lancés par tous les vaisseaux, vu que ça bouge pas mal (les projectiles sont créés et détruits très vite), ça fais tout ramer...
Marsh Posté le 02-06-2004 à 19:11:27
pfff, c galère, on se répond avec un message de retard.. hum, bref... alors pour répondre à
xterminhate a écrit : Lorsqu'un objet complexe crée à lui seul N objets dans ta liste, comment ca se passe lorsque ton objet complexe doit etre detruit ( comment sont retirés les N objets de la liste constituant ton objet complexe ) ? Gardes tu une trace de ces N objets dans la classe correspondant à ton objet complexe ? |
je dirais que si j'utilise la fameuse classe HandleC dans l'objet complexe, c'est le destructeur de cette classe qui se charge de demander à la classe ContainerP corespondante de détruire l'objet, et qui règle sa propre référence à NULL, histoire d'être bien sûr de pas accéder à l'objet qui vient d'être détruit. Mais ça, je ne l'ai ajouté que dans la dernière version de mon programme, justement pour règler le problème des plantages d'avant... mais je me demande quand même si y'a pas plus simple que tout ça...
Marsh Posté le 02-06-2004 à 19:14:01
En somme, tu as autant de listes d'objets que d'objets complexes dans le jeu ?
Marsh Posté le 02-06-2004 à 19:14:21
ah oui, et j'ai une autre question : je voudrais mettre en private certains éléments de la classe ContainerP, mais que la classe HandleC puisse quand même (et seulement cette classe) accéder aux éléments privés de la classe ContainerP. C'est possible ?
Marsh Posté le 02-06-2004 à 19:14:52
Du devrais faire un petit effort pour exploiter std::liste. Cela pourra sans doute te servir pour d'autres applications.
Marsh Posté le 02-06-2004 à 19:15:37
non non, je n'ai pas autant de listes d'objets que d'objets complexes dans le jeu ! tout est centralisé dans une seule liste (sinon ça n'a aucun intérêt).
Marsh Posté le 02-06-2004 à 19:16:42
Est ce que des classes héritent de HandleC ? si oui de quelle anière (public/private) ?
Marsh Posté le 02-06-2004 à 19:17:22
ReplyMarsh Posté le 02-06-2004 à 19:19:52
non, aucune classe n'hérite de HandleC. bon, je met un exemple, ce sera peut-être plus clair :
Code :
|
Marsh Posté le 02-06-2004 à 19:23:18
Declares protected: les membres dont tu veux restreindres l'accès à HandleC uniquement. (A vérifier, depuis que je code en asm et en C, je commence à oublier le C++, lol).
Marsh Posté le 02-06-2004 à 19:24:42
ok, merci pour le lien, je verrais ça si je dois faire un truc du genre dans le futur, mais là je me vois mal refaire tout mon code pour utiliser std::list
Marsh Posté le 02-06-2004 à 19:26:37
euh ouais, mais je les déclare comment protected ? faut bien que je mettre quelque part que c'est par rapport à HandleC que je veux restreindre l'accès (enfin laisser l'accès, plutot). C'est quoi la syntaxe ? (je suis un peu perdu depuis que MSDN ne veut plus marcher sur mon pc... oui, bon, je sais, utiliser VC++ c nul, mais bon, c le premier compilateur que j'ai eu entre les mains...)
Marsh Posté le 02-06-2004 à 19:27:12
Programmes dans le but d'apprendre un maximum de chose (les listes par exemple ). D'ailleurs, j'ai rarement vu des projes perso se terminer !
Marsh Posté le 02-06-2004 à 19:29:43
A ma connaissance tu ne peux pas restreindre à un classe dérivée en particulier.
Code :
|
Marsh Posté le 02-06-2004 à 19:30:10
En fait, mon problème (qui n'en est pas forcément un), c'est que je ne sais pas si c'est une bonne idée de vouloir tout centraliser dans un même tableau, et de surcroit d'utiliser des objets de type différents dans le même tableau... est ce que par exemple je ferais pas mieux de mettre directement
GL_Object fuselage;
et
GL_Group reacteurs;
dans ma classe vaisseau ? parce que ça compliquerais la classe vaisseau (il faudrait ajouter une fonction Draw qui appellerais les fonctions Draw de GL_Object et GL_Group) mais d'un autres coté ça simplifierais pas mal la gestion de la mémoire... dilemme... et niveau performances, je sais pas ce qui est le mieux (m'est avis que ça dois pas changer grand chose)
Marsh Posté le 02-06-2004 à 19:31:10
ben le problème c'est que HandleC n'a aucun lien avec ContainerP, enfin aucune n'est dérivée de l'autre... c'est quoi, les classes amies ?
Marsh Posté le 02-06-2004 à 19:32:28
Ce que tu as fais est correct. Tous tes objets dérives d'une classe (plus ou moins) abstraite n'est ce pas ?
Marsh Posté le 02-06-2004 à 19:33:16
Ah pardon, je croyais que HandleC dérivait de ContainerP... ca se complique un peu la
Marsh Posté le 02-06-2004 à 19:33:22
oui, c'est exactement ça, pour le coup de la dérivation de la classe plus ou moins abstraite
Marsh Posté le 02-06-2004 à 19:35:21
en fait le seul lien que HandleC a avec ContainerP, c'est le pointeur ContainerP<T1> *owner; qui permet de savoir dans quel tableau est stocké l'objet
Marsh Posté le 02-06-2004 à 19:37:06
et je voudrais justement que par l'intermédiaire de ce pointeur, il puisse demander au tableau de supprimer l'objet (quand on détruit l'instance de HandleC), mais par le biais d'une fonction spéciale (DeleteH) qu'il est le seul à pouvoir employer
Marsh Posté le 02-06-2004 à 19:42:44
Tu as essayé de faire un diagramme de l'architecture de ton programme (classes, héritages, ...etc ?).
Ps: J'ai du mal a reflechir quand j'ai faim, désolé
Marsh Posté le 02-06-2004 à 19:42:47
le truc, c que dans le tableau, les objets peuvent être créés de deux moyens : par un objet HandleC, ou alors directement. et quand je détruit le tableau, je voudrais m'assurer que tous les objets créer par le biais de HandleC ont déjà été détruits (pour être sûr qu'il n'y a pas de soucis de mémoire). de plus, il ne faut pas qu'on puisse directement détruire un objet qui a été créé par le biais de HandleC, car sinon, HandleC aurait une référence sur un objet détruit... bref, mon problème est que plusieurs objets ont des pointeurs sur un même objet, et qu'il faut qu'ils soient tous synchronisés : il ne faut surtout pas que l'un d'eux pointent sur un objet détruit...
Marsh Posté le 02-06-2004 à 19:44:34
mdr, euh ben de toute façon, moi aussi j'ai faim, et de plus ma copine (qui a finis ses partiels aujourd'hui) organise un apéro avec des potes (je viens de m'en souvenir, ou plutot elle viens de m'en souvenir en m'appelant), donc faut que j'y aille... j'ai jamais essayé de faire un diagramme, mais même si j'en fais un, j'aurais du mal à l'envoyer sur internet, nan ? bon, ben je reviens pas avant demain, alors...
Marsh Posté le 02-06-2004 à 19:45:30
Pourquoi tu voudrais detruire ce tableau... ++
Marsh Posté le 02-06-2004 à 19:46:13
ben quand on quitte le programme... juste histoire de vérifier qu'il n'y a eu aucun soucis tout au long de l'éxécution...
Marsh Posté le 02-06-2004 à 19:46:37
et bien on revient sur l'idée du singleton...
Marsh Posté le 03-06-2004 à 09:32:31
ouais, sauf que je ne sais toujours pas ce que c'est qu'un singleton...
Marsh Posté le 03-06-2004 à 09:51:57
un singleton est un objet à instance unique.
Son principe repose sur le controle du nbre d'instance de la classe
en rendant private les constructeurs de la classe.
Un exemple simple :
Code :
|
L'accés se fait ensuite via :
Code :
|
Marsh Posté le 02-06-2004 à 18:08:48
Alors voilà, je suis en train de coder un "jeu" utilisant OpenGL, mais je me pose pas mal de questions metaphysiques sur ma façon de procéder. Je précise pour commencer que je n'ai jamais eu de cours de C++, donc je prierais par avance Taz d'éviter de se foutre de ma gueule si j'ai fais des trucs pas catholiques, je commence mes premiers vrais cours d'info l'année prochaine. Mais bref, voilà ma question :
J'ai créé une librairie pour gérer tout ce qui est affichage OpenGL : le principe est que lorsque mon programme veut créer un objet 3D, il demande à cette librairie un pointeur sur un objet de classe GL_Node. De cette classe sont dérivées tous les types d'objets gérés par mon programme : GL_Face, GL_Object (plusieurs faces), GL_Group (plusieurs objets), GL_Sprite, etc... Pour savoir quel objet ma librairie doit créer, je lui passe un pointeur NULL du type qui va bien (par exemple GL_Face) qui est récupérer par un fonction template qui va créer le bon objet :
cet objet est à la fois stocké dans l'objet 'nodes' qui contient tous les objets 3D créés, et renvoyé au programme principal (sous forme de pointeur), pour qu'il puisse le modifier. ensuite, dans mon programme principal, j'ai juste à appeler une fonction Draw() et la librairie s'occupe d'afficher tous les objets déjà créés. Le tout simplifie pas mal mon programme principal, puisqu'il n'y a plus rien à gérer au niveau de l'affichage : il suffit de créer un objet, il sera dessiner tout seul au bon moment. Mais le tout est assez complexe, et il m'est arrivé d'avoir des gros soucis dans un programme précédent fonctionnant sur le même principe : le programme portait sur des vaisseaux spatiaux qui contiennent chacun un certain nombre d'équipement, eux même contenant d'autres équipements (exemple : le vaisseau possède une tourelle sur laquelle sont montés des cannons), le tout avec des classes dérivées dans tous les sens, et au moment de détruire un vaisseau, certains objets 3D étaient détruis, mais le programme cherchait encore à les dessiner, d'où problème... bref, ma nouvelle version du programme a l'air de mieux fonctionner pour le moment, mais je sais pas ce que ça va donner quand j'aurais plus avancé... donc si quelqu'un peut me dire si ma méthode semble bien, ou pas, et s'il y a mieux ou plus simple... merci d'avance (et merci déjà d'avoir tout lu ) et désolé si j'ai pas été clair