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 :

Comment gérer un nombre inconnu d'objet ?


Sujet :

C++

  1. #21
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Heu, si j'ai comprit, tu me coseil de faire une classe par objet ?
    Je pense plutot faire une classe par "type" d'objet . Mais je suis ouvert a toute proposition :p merci

    Donc en fait ca revient a faire comme je l'avais évoqué avant : toutes mes classe dérivent de cItem qui contient juste un menbre du style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    string identifiant ;
    Et toi tu propose d'ajouter un deuxieme identifiant pour savoir quel type d'objet va être a chargé c'est cela ? oui c'est une idée :p mais je pense qu'un fois le gros du travail résolu, ca ira vite sur les petit sdétails comme ca ! mais merci quand meme !!!

  2. #22
    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 : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    heu, juste une question, concernant mon cItem * tab[100] j'ai bon sur la signification ou pas ?
    Oui

    Tu as une solution très simple pour ton problème, qui est pratiquement similaire au gestionnaire de ressource que je décris dans mes tutos, à savoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    struct cItem
    {
        string Id;
    };
     
    class cTruc : public cItem
    {
        // ...
    };
    class cMachin : public cItem
    {
        // ...
    };
    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
    class cItemManager
    {
    public :
     
        template <class T> T* Get(const string& Id) const
        {
            // Recherche dans la map et renvoie du pointeur casté en T*
        }
     
        void Add(cItem* Item, const string& Id)
        {
            Items[Id] = Item;
        }
     
        void Remove(const string& Id)
        {
            Items.remove(Id);
        }
     
    private :
     
        map<string, cItem*> Items;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cPerso* Gerard = cItemManager::Instance().Get<cPerso>("Gerard");
    cMap* Village = cItemManager::Instance().Get<cMap>("Village");
    Hypothèses : le gestionnaire d'items ne s'occupe que du stockage des objets, leur bon chargement est effectué par une autre classe.

    Inconvénient : le type réel des objets est perdu, et retrouvé à l'aide d'un cast barbare. Si tu demandes "Maison" en tant que cBatiment alors que c'est un cCarte, le compilo n'y verra que du feu et tu te retrouveras avec un segfault pas facile à debusquer.

    Avantages : c'est simple, ça fait parfaitement le job, et ça marche pour toute classe pour peu qu'elle dérive de cItem. Après tu peux automatiser la gestion / destruction des items, via la classe cItem, le comptage de références et des pointeurs intelligents améliorés.

    Bien sûr c'est une vision des choses, mais qui je pense colle bien avec ce que tu souhaites. On pourrait très bien imaginer d'autres modèles : une fabrique plus "évoluée" qui prend en charge également l'importation automatique des ressources (cf. MediaManager dans mes tutos), ou encore un système plus classique avec un gestionnaire par classe de ressource.

  3. #23
    Membre émérite
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Points : 2 568
    Points
    2 568
    Par défaut
    Citation Envoyé par Clad3
    Heu, si j'ai comprit, tu me coseil de faire une classe par objet ?
    Je pense plutot faire une classe par "type" d'objet . Mais je suis ouvert a toute proposition :p merci
    Non pas une classe par objet mais comme tu le dis une classe par type d'objet

    String identifiant oui c'est comme le int identifiant, même principe.

  4. #24
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Ouha un grand merci encore loulou
    J'étais justement entrain de me lancer dans le codage de tout ca pour voir de plus prés comment ca allait se goupiller !

    Bon je vais détailler ca au fur et a mesur histoire de voir si j'ai bien tout pigé ... avant de continuer de coder la chose !
    struct cItem
    {
    string Id;
    };

    class cTruc : public cItem
    {
    // ...
    };
    class cMachin : public cItem
    {
    // ...
    };
    Pour l'instant on est d'accord, j'avais la même vision de la chose ! ( sauf que je cré une classe cItem et non une struct ... mais bon c'est juste que je suis allergique de naissance au struct ... allez savoir pourquoi lol !)

    Concernant la classe cItemManager que tu décrit, je ne vois pas grand chose a y redire ... il me restera juste a l'implementer pour voir si des petit probleme persiste ... mais rien de bien méchant a mon avis .

    Ensuite le détail qui me turlupine encore , et je crois que c'est ce que tu évoque en disant a la fin de ton message qu'on peut faire évolué cette factory en lui faisant importer ( donc créer ) automatiquement les ressources .

    En fait, si je fait par exemple comme tu dit , c a d en créant une seconde classe pour le chargement même des données ( au fait, j'aime beaucoup l'idée de séparé le stockage et le chargement des items ^^ merci )
    Je ne vois pas comment Créer l'item !!

    Pour l'ajouter je suppose que ca ira :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    cItemManager::instance().Add( &MonItem,"gerard" ) ;
    Mais comment créer ce "MonItem" ... la je seche :/

    Enfin, encore merci pour ce jolie post ... ca ma permis de bien mieux cerner les choses !

  5. #25
    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 : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    sauf que je cré une classe cItem et non une struct ... mais bon c'est juste que je suis allergique de naissance au struct
    Oui j'utilise souvent des struct dans mes exemples sur les forums, mais c'est simplement un raccourci, lorsqu'il y a peu de données et toutes publiques, pour ne pas écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class xxx
    {
    public :
        // ....
    Ce qui est tout à fait équivalent. D'ailleurs... c'était inutile dans mon post précédent, car typiquement l'identifiant sera protegé ou privé
    Bref.

    Pour l'ajouter je suppose que ca ira :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cItemManager::instance().Add( &MonItem,"gerard" ) ;
    Tout à fait, au détail près que tu ajouteras un objet alloué dynamiquement et non l'adresse d'un objet automatique, donc pas de & (ok c'est un détail, mais sait-on jamais, parfois ça évite des erreurs bêtes).
    Ou alors, comme l'identifiant est déjà associé aux instances de cItem (puisque c'est une donnée membre) tu peux automatiser l'ajout, dans le constructeur de cItem ou dans une fonction de chargement des cItem.

    Mais comment créer ce "MonItem" ... la je seche :/
    Ca dépend, principalement de la manière dont tous tes objets vont être exprimés à l'exterieur de ton appli (dans des fichiers). Il va falloir préciser un peu cet aspect je pense, pour trouver une jolie solution.
    Est-ce que 1 fichier = 1 objet ? 1 fichier = un niveau ? Est-ce que le contenu des fichiers sera + ou - similaire pour chaque type à charger ? ...
    Mais bon, globalement il faudra une fabrique (une vraie), que tu pourras plus ou moins customiser selon tes besoins.

  6. #26
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Oki, je pense qu'on est d'accord pour le &MonItem, en pratique on fera plutot un

    cItem * MonItem ;

    et

    cItemManager::instance().Add( MonItem,"gerard" ) ;

    C'est ca?

    Ensuite, concernant le format de mes fichiers ... j'ai une idées en tête, rien de plus .
    Surement un fichier / niveau ( enfin l'equivalent des niveau pour un jeu de plateforme par ex ) ou seront réparti tout les "item" a chargé .
    Et je pense qu'il sera aussi necessaire d'en charger d'autre au fur et a mesur dans les niveaux ...
    Heu sinon , oui je pense que le contenu des fichier seront a peu prés les meme pour plusieur item d'un meme type mais pas d'un type a l'autre . ( par contre, je pense que se sera dans tout les cas assez simple ; des valeurs associé a chaque caractére ; le tout permettant de décrire l'objet ... )
    A mediter ^^

  7. #27
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    I'm back !
    Re bonjour a tous !
    Aprés une petite journée de méditation j'ai pensé a une solution pour gérer la création des item eux meme ... Bon ce n'est certainement ( surement ) pas une methode trés propre ni trés optimale ...mais c'est un début ...et je pense que ca peut marcher .... Je m'en vais vous comter son histoire

    Il était une fois ....
    Alors, on reprend nos classe précédente ( cItem et cItemManager )

    Pour le chargement, on utilise une classe cLoader qui va procéder de la sorte .

    ( on va admetre que la récupération des données dans un fichier se fait de maniére inutuitive ... )

    Elle possédera une methode init()
    ->Celle ci sera la methode principale, elle parcourera un fichier donné
    et a chaque nouvel objet décrit, elle apellera une fonction précise, propre a chaque TYPE d'objet a charger . Et ce ainsi de suite, jusqu'a ce que tout les objets soit créer / stockés en mémoire .

    Toute ses sous-fonction seront bati sur le meme principe .
    Elle vont affecter les donnée caractérisant l'objet a des variables menbre d'une classe singleton représentant le type d'objet a créer .

    ex:
    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
     
    void BatimentLoader()
    {
       cBatimentModel::Instance().nom = maison de jean
       cBatimentModel::Instance().taille = 2
       cBatimentModel::Instance().poid = 100
       cBatimentModel::Instance().prix = 200
    }
     
    void ArmeLoader()
    {
      cArmeModel::Instance().nom = pistolet
      cArmeModel::Instance().puissance = 23
      cArmeModel::Instance().portée = 2
    }
    En version simplifié car ces données ( maison de jean , 2, 100 ect...) seront lu a partir d'un fichier du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    [BATIMENT]
    nom = maison de jean
    taille = 2
    100
    prix = 200
    [/BATIMENT]
     
    [ARME]
    nom = pistolet
    puissance = 23
    portée = 2
    [/ARME]
    Pourquoi faire comme ca ? Je sais pas trop ... ms je ne vois pas la version + simple ( j'aime bien les chose compliqué pr rien ^^ )

    Ensuite , on a donc en mémoire les carac de notre objet accessible a tout instant . il ne nous reste plus qu'a le crée :

    Dans les 2 fonctions décritent + haut, on ajoute qquchose du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    cItemManager::instance().Add( new cBatiment() ,"maison de jean1" ) ; 
    cItemManager::instance().Add( new cArme() ,"pistolet_debut" ) ;
    Ensuite, dans chaque constructeur de cBatiment , cArme ect ... on apelle une fonction init() qui se charge d'affecter les valeur des variable de la cMaClasseModel a mon objet courant ( possédant exactement les meme variable menbre .

    nous voila donc avec nos objets créer et stocker en mémoire ....

    2 questions me viennent a l'esprit
    1) L'idée est bonne? ( dans le sens : " ca peut marcher ?"
    2) Comment on améliore cette horreur ?

    A pluche les jeunes !

  8. #28
    Membre émérite
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Points : 2 568
    Points
    2 568
    Par défaut
    Si j'ai bien compris ce que tu as expliqué, j'ai déjà fait un truc quasi pareil, et cela fonctionne

    Donc

  9. #29
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Voila ce que j'ai fait jusqu'a présent ... je n'ai aps encore testé, mais je pense qu'il n'y a pas trop d'erreur ... enfin ca compile ^^

    citem.h

    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
     
    #ifndef CLASSE_CITEM
    #define CLASSE_CITEM
     
    #include <string>
     
    /* --------------------------------------------------------------------------------- */
    // Classe 'abstraite' représentant une entiée quelquonque dans le jeu .
    /* --------------------------------------------------------------------------------- */ 
     
    class cItem
    {        
      public :
    		   cItem ();
    		   ~cItem ();              
      public :
    	       std::string id ;
    };
     
    #endif
    cItem.cpp

    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
     
    #include "cItem.h"
     
    /* --------------------------------------------------------------------------------- */
    // constructeur simple 
    /* --------------------------------------------------------------------------------- */ 
     
    cItem::cItem()  
    { 
     
    }
     
    /* --------------------------------------------------------------------------------- */
    // destructeur simple 
    /* --------------------------------------------------------------------------------- */ 
     
    cItem::~cItem() 
    {
     
    }
    cRessourcesManager.h
    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
     
    #ifndef CLASSE_CRESSOURCESMANAGER
    #define CLASSE_CRESSOURCESMANAGER
     
    #include <string>
    #include <map>
    #include <iostream> 
    #include "cItem.h"
     
    /* --------------------------------------------------------------------------------- */
    // Classe permettant de stocker en mémoire les différentes entitées du jeu .
    /* --------------------------------------------------------------------------------- */ 
     
    class cRessourcesManager
    {
      private :
              cRessourcesManager ();
      public :
              ~cRessourcesManager();
              static cRessourcesManager & GetInstance(); 
    		  void add(const std::string & Id, cItem * item );
    		  void remove(const std::string & Id);
    		  template < class T > T * get( const std::string & Id ) const
    		  {
    			  std::map<std::string, cItem *>::iterator it;
    			  if ( Items.find(Id) == Items.end() )
    			  {
    				  std::cout << " Erreur ( classe cRessourcesManager ) " << std::endl ; 
    			  }
    			  else
    			  {
    				  return  (T *) * it;
    			  }
     
    		  }
     
      public :
    	      std::map<std::string, cItem*> Items ;
    };
     
    #endif
    cRessourcesManager.cpp
    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
     
    #include "cRessourcesManager.h"
     
    /* --------------------------------------------------------------------------------- */
    // constructeur simple 
    /* --------------------------------------------------------------------------------- */ 
     
    cRessourcesManager::cRessourcesManager()  
    { 
     
    }
     
    /* --------------------------------------------------------------------------------- */
    // destructeur simple 
    /* --------------------------------------------------------------------------------- */ 
     
    cRessourcesManager::~cRessourcesManager() 
    {
     
    }
     
    /* --------------------------------------------------------------------------------- */
    // Un Handle sur notre instance
    /* --------------------------------------------------------------------------------- */ 
     
    cRessourcesManager & cRessourcesManager::GetInstance()  
    { 
    	static cRessourcesManager instance ;
    	return instance ;  
    }
     
    /* --------------------------------------------------------------------------------- */
    // Permet d'ajouter en mémoire une entitée dans notre conteneur . ( map )
    /* --------------------------------------------------------------------------------- */ 
     
    void cRessourcesManager::add(const std::string & Id ,cItem * item)  
    { 
    	Items[Id] = item ;
    }
     
    /* --------------------------------------------------------------------------------- */
    // Permet de détruire la mémoire alloué à une entitée dans notre conteneur . ( map )
    /* --------------------------------------------------------------------------------- */ 
     
    void cRessourcesManager::remove(const std::string & Id )  
    { 
    	Items.erase(Id) ;
    }
    et voila pour le moment

Discussions similaires

  1. Réponses: 13
    Dernier message: 25/05/2010, 07h44
  2. Comment lister un nombre inconnu de sous repertoires ?
    Par liocifer dans le forum VBScript
    Réponses: 2
    Dernier message: 02/06/2008, 19h50
  3. Comment gérer le style d'un objet créé dynamiquement
    Par Delphi-ne dans le forum ASP.NET
    Réponses: 3
    Dernier message: 05/02/2008, 16h12
  4. gérer un nombre inconnu d'input text
    Par Ludosjob dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 11/05/2007, 16h22
  5. comment gérer un nombre non fixe de paramètres entrant ?
    Par c_moi_c_moi dans le forum SAP Crystal Reports
    Réponses: 4
    Dernier message: 28/03/2006, 12h05

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