IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Destruction de plateau à HeroQuest


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 61
    Par défaut Destruction de plateau à HeroQuest
    Bonjour,

    Voilà, je m'excuse d'avance car le post risque d'être assez long, mon problème portant sur une implémentation objet assez conséquente.

    Je suis actuellement avec un ami en train de développer une version pc du jeu de plateau HeroQuest, en utilisant le C++ et la librarie graphique Allegro - je le précise, même si dans le cas présent on s'en moque un peu vous verrez -. Et nous rencontrons un problème au niveau de la destruction de notre objet plateau.

    C'est là que je dois m'expliquer. Je vous passe les méthodes à chaque fois, mais voici à quoi ressemblent nos classes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    class p_plateau
        {
        protected :
            std::string nom_quete;	// Nom de la quête
            std::string description_quete;	// Description de la quete
            int type_quete;		// 0 CHASSER / 1 SAUVER
            u_liste * cibles;		// La liste - chainée - des cibles
    				// de la quête
            p_salle * salles[34];		// Le tableau des salles du plateau.
            p_case * matrice_plateau[26][19];// La matrice des cases
            BITMAP * buffer_plateau;	// Le BITMAP * dans lequel on dessine
    	}
     
    class p_salle
        {
        protected :
            std::string adresse_texture;	// L'adresse de la texture des
    				// cases de la salle.
            int nb_cases;	// Nombre de case
            p_case ** cases;	// Tableau des cases de la salle
            u_liste * contenu;	// La liste - chainée - des positionnables
            BITMAP * texture;	// Le BITMAP * de la texture
        };
     
    class p_case : public u_point
        {
        protected :
            int visible;		// 0 Invisible - 1 Visible
            int bordure[4];	// Les propriétés des bords de la case 
    			// (0 rien/1 mur /2 porte/..)
            p_salle ** salles;	// Tableaux des salles auxquelles
    			// appartient la case
            u_liste * contenu;	// La liste - chainée - des positionnables
            BITMAP * buffer;	// Le BITMAP * dans lequel on dessine
           };
     
    /*	
    Exemple de positionnables : un gobelin, un héro, un piège hérissé de lance,
    un chevalet de torture, un sarcophage, bref n'importe quoi qui se pose
    sur le plateau.
    */
     
    class u_point
        {
        protected :
            int x;
            int y;
        };
     
    /* Deux classes pour la création et la gestion 
       de listes chainées d'élément de tous poils. */
     
    class u_liste
        {
        protected :
            u_noeud * tete;
            u_noeud * courant;
            int nb_elements;
        };
     
    class u_noeud
        {
        protected :
            void * valeur;
            u_noeud * suivant;
        };
    Au moment de la destruction du plateau, nous devons détruire un très grand nombre d'objets (494 cases, 34 salles, et tout les contenus), et il semblerait que nous nous emmelions un peu les pinceaux.
    Pour éviter toute tentative de destruction sur des objets déjà disparus, nous prenons pourtant soin, dans le destructeur de salle de passer à null le pointeur de chaque noeud de contenu et dans le destructeur de plateau d'en faire autant avec la liste des cibles. Ainsi tous les différents contenu ne sont plus connus qu'une fois, au travers du contenu des salles.

    Voici le code des différents destructeurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
     
    ~plateau()
        {
        int i, j;
     
        // Mise à NULL de tous les pointeur vers les objets cibles.
        if(cibles->get_tete()!=NULL)
            {
            cibles->init();
            while(cibles->is_suivant())
                {
                cibles->get_courant()->set_valeur(NULL);
                cibles->go_suivant();
                }
            }
        delete cibles;
     
        // Destruction des cases du plateau
        for(i=0;i<26;i++)
            {
            for(j=0;j<19;j++)
                {
                delete matrice_plateau[i][j];    
                }    
            }
        delete matrice_plateau;
     
        // Destruction des salles
        for(i=0;i<34;i++)
            {
            delete salles[i];    
            }
        delete salles;
     
        // Destruction du BITMAP * où dessiner le plateau
        destroy_bitmap(buffer_plateau);
        }
     
    ~p_salle()
        {
        // Mise à NULL de tous les pointeur vers les objets contenu dans la salle
        if(contenu->get_tete()!=NULL)
            {
            contenu->init();
            while(contenu->is_suivant())
                {
                contenu->get_courant()->set_valeur(NULL);
                contenu->go_suivant();
                }
            }
        delete contenu;
     
        // Destruction du tableau de cases
        delete cases;
     
        // Destruction de la texture en mémoire
        destroy_bitmap(texture);
        }
     
    ~p_case()
        {
        // Destruction du tableau de salles
        delete salles;
        // Destruction du contenu
        //  - cette fois les pointeur on concervés leur valeur -
        delete contenu;
     
        destroy_bitmap(buffer);
        }
     
    ~u_liste()
        {
        int i;
        u_noeud * parcours=tete, * suivant;
     
        // Par cours de la liste et destruction de chacun de ses noeuds.
        for(i=0;i<nb_elements;i++)
            {
            suivant=parcours->get_suivant();
            delete parcours;
            parcours=suivant;
            }
        }
     
    ~u_noeud()
        {
        // Destruction de l'objet porté par le noeud
        delete valeur;
        }
    Voilà, merci d'avoir eu le courage de lire tout ceci, et merci d'avance à tout ceux pourrait nous apporter leur aide.

    Parce que la solution pour que ca tourne pour le moment, c'est de commenter intégralement le destructeur de plateau :=°

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Je ne sais pas si les données membres qui ont le même type et le même nom dans les différentes classes désignent le même objet physique, mais si c'est le cas alors oui tu détruis ces objets plusieurs fois.

    Pourquoi ne pas utiliser std::list pour tes listes chaînées ? Et correctement définir quelle (seule et unique) classe va posséder chacune et gérer sa durée de vie ? Ou si c'est plus compliqué (tu ne sais pas qui va devoir détruire qui), pourquoi ne pas utiliser des pointeurs intelligents ?
    http://miles.developpez.com/tutoriel...oost/smartptrs

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 61
    Par défaut
    Citation Envoyé par Laurent Gomila
    des pointeurs intelligents ?
    Humm, euh j'avoue, c'est la première fois que j'entends parler de pointeur intelligents... J'ai parcouru rapidement le tuto du lien, ca a l'air relativement puissant, une fois qu'on sait s'en servir :/

    Et je dois dire qu'au point où nous en sommes - et avec le délai qu'il nous reste (9 jours :$ ) -, je nous vois mal reprendre l'ensemble pour gérer des pointeurs intelligents....

    Existerait-il un moyen - plus ou moins simple dans la mesure du possible - de tester où ca plante ?

    Folken, étudiant codant son premier jeu en galère :/

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    C'est simple à utiliser pourtant
    Dans ton cas, pour commencer, tu remplaces tes pointeurs par des pointeurs intelligents, aucun souci.
    Pour la suite, essaie d'éviter de recoder une liste maison en C alors que ça existe en C++ - std::list - et que c'est super bien géré - avec des pointeurs intelligents, c'est encore plus puissant -, et que ça t'évite carrément d'avoir un destructeur. Durée de l'opération de refactoring, environ 1/2 journée, je viens de le faire pour un autre tuto avec gestion des pointeurs intelligents à ajouter et une liste maison à supprimer.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 61
    Par défaut
    Je vais me pencher sur l'utilisation des std::list et des pointeurs intelligents. Je pense en avoir effectivement pour une demi-journée de boulot, je verrais ca demain matin.

    Merci à vous pour les conseils.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 61
    Par défaut
    Je me permet de remonter le sujet car nous en arrivons à ... une nouvelle impasse ^^

    Pour gérer les contenu, nous voulions utiliser std::list plutot que notre classe maison - effectivement, c'est beaucoup mieux -, mais en même temps, nous aimerions utiliser les pointeurs intelligents - et en particulier les shared_ptr - pour gérer les objets présents sur le plateau et dans les inventaires - avec toutes les références multiples que je vous expliquait plus haut -.

    Mais les shared_ptr sont apparemment incompatibles avec une gestion par liste chainée...

    Devons nous perdre la simplicité de gestion des std::list, et nous repencher sérieusement sur nos destructeur pour désallouer convenablement notre mémoire, ou bien au contraire conserver cette facilité de gestion des objets, et retourner jouer avec des tableaux ? ...

    Un conseil ? Merci d'avance.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. destruction d'une classe qui herite de CDialog
    Par philippe V dans le forum MFC
    Réponses: 2
    Dernier message: 03/02/2004, 17h39
  2. Réponses: 2
    Dernier message: 17/08/2003, 20h07
  3. Probleme de destruction
    Par Merluco dans le forum Langage
    Réponses: 6
    Dernier message: 30/06/2003, 13h51
  4. Création/Destruction
    Par HT dans le forum Langage
    Réponses: 5
    Dernier message: 22/05/2003, 17h04
  5. Réponses: 7
    Dernier message: 18/04/2003, 10h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo