[C/C++] Initialiser la taille d'un tableau, membre d'une classe mère

Le côté programmation du développement d'un jeu vidéo.

Messagepar Gabriel » 15 Sep 2011, 20:42

Appeler new et delete (ou mieux, utiliser la solution d'Eva) ce n'est pas "réinventer la roue", c'est utiliser des fonctionnalités qui ont été faites pour ça.


Bravo, maintenant tu peux l'appliquer.

Et je ne vois pas en quoi tu perds en robustesse, au contraire en utilisant uniquement ce dont tu as besoin tu réduit la surface potentielle de bugs et tu simplifies la logique et la lisibilité de ton programme.


Tu réduis, par exemple, les risques de memory leak. De plus, pour la simplicité, tu peux profiter de tous les algorithmes qui sont fourni avec, genre, si tu veux trier ton tableau.

J'ai toujours pas compris, pourquoi vous voulez pas utiliser std::vector.

Ajouter "bien plus de choses" que tu n'en as besoin n'est PAS une bonne chose !


Tu me demandais pourquoi utiliser les std::vector, je te réponds que c'est pareil, sauf que tu peux profiter de bien plus de choses, donc au final, tu as ton tableau que tu peux utiliser de la même façon, mais en plus, tu peux profiter si tu veux, des algorithmes de tris, le redimensionnement dynamique, etc. mais ça implique pas que tu les utilises.

Et étant donné que c'est le deuxième thread où Nieluj rencontre des problèmes avec std::vector, j'ai des doutes sur le côté "ça simplifie la vie".


Oui, surtout quand le problème ne vient pas des std::vector.

Si, je t'ai répondu mais tu vois ça comme des avantage. A partir de là je ne peux vraiment rien faire de plus.

Aucune discussion n'est possible quand on ne part pas des même axiomes.


On est d'accord. Bon personnellement, j'arrête de répondre, ça amènera à rien.
Avatar de l’utilisateur
Gabriel
 
Messages: 311
Inscription: 25 Fév 2006, 10:15

Messagepar Eva » 16 Sep 2011, 01:02

Nieluj a écrit:Faut pas s'énerver pour si peu les enfants :) . Formons nous les un les autres mais avec un peu d'humilité si possible.


L'humilité c'est pour ceux qui ne sont pas sûrs d'eux.
Avatar de l’utilisateur
Eva
Hello World, I'm new !
 
Messages: 651
Inscription: 31 Mai 2005, 15:43

Messagepar Nieluj » 16 Sep 2011, 10:31

Eva a écrit:L'humilité c'est pour ceux qui ne sont pas sûrs d'eux.


L'humilité c'est savoir prendre du recul par rapport à un ensemble, comprendre que rien n'est immuable et qu'aucun paradigme n'est vrai dans l'absolue. Être sûr de soi, c'est justement aller à l'encontre de l'humilité.

Un nouveau débat dans un même sujet, philosophique cette fois :00000031:


Sinon, pour revenir sur les vecteurs, j'ai une nouvelle question ( histoire que ce sujet ne parte pas plus en cacahuète ).

Je stocke des références d'objets dans un vecteur ( on ne s'offusque pas s'il vous plait :00000030: ). Lorsque je delete un objet dont la référence est stockée dans ce vecteur, je suis confronté à un segment fault du fait que ces références sont utilisées lors de traitements.

J'ai donc pensé à utiliser un nouveau vecteur "corbeille" dans lequel je stockerai les éléments à supprimer ( bien entendu en les enlevant du vecteur d'origine ) et de faire les delete seulement si ce vecteur contient des éléments.

Ma première question : Est ce que c'est une bonne idée, sinon y a-t-il un meilleur moyen ?

Ma deuxième question : Quel est le meilleur moyen d'identifier les éléments dans le vecteur, étant donnée qu'actuellement je les stock avec push_back ?
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar teto » 16 Sep 2011, 15:07

Je stocke des références d'objets dans un vecteur ( on ne s'offusque pas s'il vous plait ).

C'est possible ca ? le vector accepte que des objets autoconstructibles et une référence ca doit être initialisé lors de sa déclaration non ? apparemment oui si t'arrives mais perso j'éviterai. Autrement std::shared_ptr + weak_ptr etc...

Cet article peut t'offrir qques pistes de réflexions sur les vecteurs (double buffer)
http://games-creators.org/wiki/Gestion_memoire_des_projectiles_dans_un_shoot_them_up

Ma deuxième question : Quel est le meilleur moyen d'identifier les éléments dans le vecteur, étant donnée qu'actuellement je les stock avec push_back ?

Par leur position, what else ?
Avatar de l’utilisateur
teto
 
Messages: 1168
Inscription: 26 Juil 2005, 19:02
Localisation: /home/Paris

Messagepar Nieluj » 16 Sep 2011, 16:00

1) Bah je stock des pointeurs quoi :

Code: Tout sélectionner
Monster* monster1 = new Monster();
vector.puch_back( monster1 );


2) Ca je suis plutôt d'accord, mais il faut donc stocker cette position au sein de l'objet lors de l'insertion dans le vecteur.. C'est pas un peu étrange ?

Edit : Merci pour le lien c'est exactement ce qu'il me faut.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar teto » 16 Sep 2011, 16:15

1/ Une référence ca n'est pas pareil qu'un pointeur :
Monster& monster1 = Monster();
!=
Monster* monster1 = new Monster();

2/ Si c'est pour faire une boucle for sur le container pas besoin des indices. Sinon tu peux enregistrer l'index du Monster via montster->id = 4;
ou bien t'utilises un std::map (et si t'es en C++0x, t'as unordered_map si tu veux pas ajouter un operator< dans ta classe)
Avatar de l’utilisateur
teto
 
Messages: 1168
Inscription: 26 Juil 2005, 19:02
Localisation: /home/Paris

Messagepar Nieluj » 18 Sep 2011, 10:19

Je suis parti sur la solution d'associer l'index courant à l'élément inséré lors de sa création. Lors de la suppression de l'objet, dans son destructeur je fais un erase à l'index correspondant à cet objet. Le problème c'est qu'il va falloir que je réorganise le vecteur et les index de chaque éléments se trouvant après l'élément enlevé. J'ai peur que ce ne soit un peu trop lourd.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Eva » 18 Sep 2011, 13:56

Pourquoi t'as besoin d'identifier tes objets de cette façon ?..
Avatar de l’utilisateur
Eva
Hello World, I'm new !
 
Messages: 651
Inscription: 31 Mai 2005, 15:43

Messagepar Nieluj » 18 Sep 2011, 14:36

Parce que je ne vois pas d'autres solution en utilisant un vecteur en fait.. Il faut bien que j'enregistre l'index qui correspond à l'objet si je veux récupérer ce denier dans le vecteur.

L'utilisation de map me permettrait de supprimer un éléments sans qu'il y ait un décalage des données si j'ai bien compris ? Et donc je n'aurais plus besoin de décrémenter l'index des éléments suivants l'élément supprimé dans ce cas.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Eva » 18 Sep 2011, 14:39

Ouais, c'est pas ma question.

Ce que je te demande c'est : pourquoi tu as besoin de récupérer l'objet dans le vecteur à partir de cet objet ?

C'est pour récupérer la position de l'objet ? Son numéro d'ordre par rapport aux autres objets ?

C'est quoi la raison, d'un point de vue fonctionnel, qui fait que t'as besoin de ça ?
Avatar de l’utilisateur
Eva
Hello World, I'm new !
 
Messages: 651
Inscription: 31 Mai 2005, 15:43

Messagepar Nieluj » 18 Sep 2011, 15:28

J'ai une classe Environment qui contient un vecteur WeaponObjects dans lequel sont stockés tout ce qui est projectiles. En l'occurrence, je stock dans ce vecteur des objets de type FireBall .

Dans la classe FireBall, j'ai une méthode HandleBehavior dans laquelle je gère son comportement. Lorsque cette méthode détecte une collision vers la gauche ou vers la droite je supprime l'objet ( à noter que dans le destructeur j'appelle la méthode permettant de faire le erase correspondant dans le vecteur )

Je dois également supprimer l'élément du vecteur WeaponObjects correspondant sinon je me retrouve logiquement avec un segment fault. C'est donc là que j'ai besoin de faire la liaison entre l'objet FireBall et sa position dans le vecteur WeaponObjects.

J'espère avoir répondu à ta question.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar teto » 18 Sep 2011, 18:59

Il y a plusieurs méthodes pour faire autrement:
-un code retour de HandleBehavior qui indique qu'il faut la supprimer
-tu mets une variable membre de ta classe "EnVie" à "Faux"
-etc..


Si l'ordre n'est pas important quand tu l'enleves de ton vecteur, fais std::swap() entre l'élément en question et le dernier élément du vecteur, ca évitera que std::vector décale toutes les fireball vers la gauche lors de la suppression.
Avatar de l’utilisateur
teto
 
Messages: 1168
Inscription: 26 Juil 2005, 19:02
Localisation: /home/Paris

Messagepar Nieluj » 18 Sep 2011, 23:17

En effet, c'est pas mal du tout comme ça et ça me permet de centraliser ce genre de procédure dans une même classe ce qui me parait plus propre au final.

Du coup j'ai mis ce genre de chose en place :

Code: Tout sélectionner
 
    int weapon_size = env->weaponObjects.size();

    for( int i=0; i<weapon_size; i++ )
    {
            if( weapon_elem->active == true )
            {
                int posx_relative = weapon_elem->posx - env->map->camerax;
                int posy_relative = weapon_elem->posy - env->map->cameray;

                weapon_elem->Blit( posx_relative, posy_relative );
                weapon_elem->HandleBehavior();
            }
            else
            {
                //suppression de l'élément dans le vecteur
                env->weaponObjects.erase( env->weaponObjects.begin() + i );
                delete env->weaponObjects.at( i );
            }
    }


Mais avec ce code, si l'intervalle entre 2 FireBall détruites est très faible alors l'application se fige ( en gros ça ne fonctionne que si il y a un seul élément dans le vecteur ).

J'ai également remplacé le code entre le else par ceci afin d'éviter le décalage des données du vecteur:


Code: Tout sélectionner
               
env->weaponObjects.at( i ) = env->weaponObjects.back();
env->weaponObjects.erase( env->weaponObjects.end() );


Et là l'application se fige même avec une seule FireBall détruite... Il y a un truc que j'ai pas du piger à ce niveau.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar teto » 18 Sep 2011, 23:19

Code: Tout sélectionner
                env->weaponObjects.erase( env->weaponObjects.begin() + i );
                delete env->weaponObjects.at( i );

C'est là que tu te plantes.
Inverse les 2 lignes.

Fais gaffe à pas sauter un element en cas de suppression quand tu parcours ton vecteur.

Apparemment t'utilises pas d'iterateur non plus mais erase renvoie un iterateur valide (ce que les débutants oublient souvent de faire).
Avatar de l’utilisateur
teto
 
Messages: 1168
Inscription: 26 Juil 2005, 19:02
Localisation: /home/Paris

Messagepar Nieluj » 18 Sep 2011, 23:32

env->weaponObjects.begin() c'est un itérateur si je dis pas de bêtise.

Sinon que change le fait d'inverser ces 2 lignes ? Il me parait plus propre de supprimer l'objet à la fin.. En tout cas ça n'arrange pas mon soucis, j'ai l'impression que c'est le fait de changer la structure du vecteur alors qu'il est parcouru qui ne lui plait pas et qui fige l'application.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Nieluj » 18 Sep 2011, 23:41

Arf ça vient de ceci :
Code: Tout sélectionner
    int weapon_size = env->weaponObjects.size();

    for( int i=0; i<weapon_size; i++ )
    { ....


Bon ça a l'air de fonctionner ! Merci pour le coup de main encore une fois.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Nieluj » 18 Sep 2011, 23:45

Nieluj a écrit:Sinon que change le fait d'inverser ces 2 lignes ?


Ok je viens de me rendre compte de ma connerie ...
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Eva » 19 Sep 2011, 18:59

Ca me parait quand même vachement tordu de gérer quelque chose qui dépend du conteneur dans le contenu....
Avatar de l’utilisateur
Eva
Hello World, I'm new !
 
Messages: 651
Inscription: 31 Mai 2005, 15:43

Messagepar NewbiZ » 19 Sep 2011, 20:30

Eva a écrit:Ca me parait quand même vachement tordu de gérer quelque chose qui dépend du conteneur dans le contenu....

+1

D'ailleurs, si c'est pour stocker des éléments que tu comptes trifouiller au hasard pour les enlever, une list/deque serait plus adaptée.
~ Passer pour un idiot aux yeux d'un imbécile est une volupté de fin gourmet ~
Avatar de l’utilisateur
NewbiZ
 
Messages: 1265
Inscription: 02 Juin 2005, 22:25
Localisation: Tallinn / Estonie

Messagepar Nieluj » 20 Sep 2011, 09:52

Eva a écrit:Ca me parait quand même vachement tordu de gérer quelque chose qui dépend du conteneur dans le contenu....


C'est pas faux... Mais du coup, avec la méthode de teto ce n'est plus le cas.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Précédente

Retourner vers Programmation

Qui est en ligne

Utilisateurs parcourant ce forum: Bing [Bot] et 17 invités