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 :

structure et class


Sujet :

C++

  1. #1
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut structure et class
    bonjour

    alors voila j'ai une class personnage mais pour ce personnage on doit retenir plein d'info sur lui par exemple xp, argent, force, etc... donc je me demande ne vaut t'il pas mieux changer la class en structure. seul probleme c'est que j'ai besoin des constructeur que on ne trouve pas dans les structure du coup j'aurai besoin de conseil.

    que feriez vous ?
    quel serais la meilleur solution ?

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    De manière générale, une classe et une structure sont strictement identiques en C++, à une exception près: la visibilité par défaut de ses membres, qui est privée pour les classes et publique pour les structures.

    Ceci dit:

    Le meilleur moyen de définir des valeurs particulières pour une classe passe par son constructeur, en fournissant les arguments "qui vont bien" et, le cas échéant, en fournissant des valeurs par défaut.

    Il n'y a, a priori, aucun lien direct entre les différentes valeurs que tu peux vouloir utiliser pour ton personnage (force, xp, argent, mana, etc), il n'y a donc aucune raison de vouloir les regrouper "ailleurs" que dans ton personnage

    S'il y a des raisons pour placer des accesseurs sur ces valeurs (après tout, on s'attend de la part du personnage à ce qu'il puisse répondre à des questions comme "quelle est ta force / ton niveau / ton expérience / la somme d'argent dont tu disposes"), il n'y a pas lieu de fournir des mutateurs classiques:

    La plupart de ces valeurs seront modifiées dans certaines situations:
    • L'expérience augmente quand le personnage est avisé qu'il a tué son adversaire, dans une proportion dépendant de l'adversaire qu'il a tué (et e son propre niveau, par exemple)
    • Son mana diminue lorsqu'il décide de lancer un sort, en fonction de la quantité de mana pour ce faire et augmente quand le personnage décide de boire une potion, en fonction de la quantité de mana que la dite potion lui octroie, voir, d'une valeur donnée toutes les X secondes.
    • La somme d'argent dont il dispose augmente en fonction de ce qu'il ramasse
    • ...
    Toutes ces situations représentent autant de services que tu es sans doute en droit d'attendre de la part de ton personnage, et c'est de ce point de vue qu'il faut que tu en arrive à les manipuler
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    Je suis tout à fait d'accord avec ça mais au niveau des stats après ça fera sans doute beaucoup d'attributs privés non car si on observe bien à part les stats vie magie xp argent il faut retenir la force vitesse agilité résistance physique résistance magique force magique etc... ça fait beaucoup pour une classe non ?

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Visiblement, tu n'as pas compris ce que je voulais expliquer.

    Ton personnage manipule en interne toutes ces données, mais il n'y a pas forcément lieu de créer une classe pour représenter son niveau, une autre pour représenter sa force et une troisième pour représenter la somme d'argent dont il dispose : de "simples" valeurs numériques sont amplement suffisantes

    L'idée est d'avoir une classe "personnage" qui pourrait ressembler à quelque chose comme
    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
    class Personnage
    {
        public:
            Personnage(int level = 0, int gold=0, int strength=1, int mana=60,
                       int live = 60
                       /*, les autres auxquels je ne pense pas */):level_(level);
                       gold_(gold),strength_(strength), mana_(mana),
                       maxMana_(mana), live_(live), maxLive_(live)
                       /* tous les autres */
            {}
            /* on s'attend à pouvoir demander les différentes valeurs */
            int level() const{return level_;}
            int gold() const{return gold_;}
            int strenght () const{return strength_;}
            int mana() const{return mana_;}
            int maxMana() const{return maxMana_;}
            int live() const{return live_;}
            bool alive() const{return live_>0;}
            int maxLive() const{return maxLive_;}
            /* ce que j'ai oublié */
        private:
            int level_;
            int gold_;
            int strenght_;
            int mana_; // nombre de points de mana disponible
            int live_;  // nombre de points de vie disponible
            int maxMana_; // maximum de points de mana
            int maxLive_; // maximum de point de vie
            int experience_; // l'expérience actuelle
            int nextLevelAt_; // expérience requise pour le prochain niveau
            /* tous les autres */
            Inventaire inventory_;
    };
    Quand tu veux afficher les stats, tu n'as donc qu'à demander les différentes valeurs que tu veux afficher

    Ensuite, tu attends une série de services de la part de ton personnage, qui vont régulièrement manipuler l'une ou l'autre de ces données (ou parfois plusieurs!).

    Par exemple, on peut se dire que quand le personnage tue un ennemi, il se passe plusieurs choses simultanées:
    • il gagne un certain nombre de points d'expérience
    • il récupère une certaine somme d'argent sur l'ennemi
    • il peut récupérer certains objets d'inventaire
    • ... plein de choses qui dépendent de ton gameplay
    Certaines de ces choses peuvent d'ailleurs provoquer d'autres changements. Le fait de gagner de l'expérience peut, par exemple, te faire passer de niveau!

    Mais pour tuer un ennemi, il faut l'avoir attaqué, et c'est surtout cela qui va t'intéresser.

    Tu complèteras donc sans doute ton interface Personnage sous une forme proche de
    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
    class Personnage
    {
         /* tout ce dont j'ai parlé plus haut */
         public:
             void attack(Personnage & ennemy)
             {
                 ennemy.subitAttaque(/* ... */); 
                 if(! ennemy.alive())
                 {
                     gainXp(ennemy.xpToGain());
                     gainGold(ennemy.xpToGain());
                     pillerInventaire(ennemy.inventaire());
                 }
             }
    };
    ouppss... voila trois fonctions dont je n'ai pas parlé.

    En fait, gainXp, gainGold et pillerInventaire sont des comportements que le personnage peut avoir, mais dont on ne s'attend pas forcément à pouvoir appeler depuis "l'extérieur" (à par gainGold ou pillerInventaire )

    Il est donc bon de faire en sorte que seul les fonctions membres de Personnage puissent y avoir accès en les rendant privées, sous une forme proche de
    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 Personnage
    {
        /* tout ce dont j'ai parlé plus haut */
        private:
            void gainExperience(int toGain)
            {
                 experience_ += toGain;
                 if(experience_>= nextLevelAt_)
                 {
                     gainedLevel();
                 }
            }
            void gainGold(int toGain)
            {
                gold_ += toGain;
            }
            void pillerInventaire(Inventaire & toTake)
            {
                /* passer tous les objets  qui peuvent l'être de
                 * toTake à inventory_
                 */
            }
    };
    Et, décidément, je viens encore de rajouter une fonction inconnue: gainedLevel, qui prend "simplement" en charge les modifications à apporter lorsque l'on gagne un niveau, et qui pourrait ressembler à quelque chose comme
    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
    class Personnage
    {
        /* tout ce dont j'ai parlé plus haut */
        private:
            void gainedLevel()
            {
                level_++; 
                /* pour le prochain niveau, il faut moitié plus d'expérience que
                 * pour le niveau actuel
                 */
               nextLevelAt_ = nexLevelAt_ * 1.5;
               /* en gagnant un niveau, on augmnte d'un tiers la mana maximale
                * et la vie maximale
                */
                manaMax_ = manaMax_ *4 / 3;
                liveMax_ = liveMax_ * 4 / 3;
                /* et on se retrouve avec la mana et la vie au maximum */
                live_= liveMax_;
                mana_ = manaMax_;
            }
    };
    Bien sur, ces comportements sont tels que je les imagine moi, avec des valeurs arbitraires choisies par moi, et peuvent parfaitement être adaptés selon ton propre gameplay

    Il n'est d'ailleurs pas exclu que tu veuille pouvoir faire gagner de l'or, de l'expérience ou du matériel autrement qu'en tuant un ennemi (en terminant une quête, en vendant ou en achetant du matériel, et autres possibilités).

    Certaines des fonctions dont je viens de parler ici (comme gainExperience ou gainGold) peuvent donc se retrouver en accessibilité publique et d'autres (gainedLevel), tout en restant privées, peuvent être virtuelles pour profiter du polymorphisme, afin que les stats soient modifiées de manière différentes si le personnage est un guerrier, un archer ou un magicien

    Mais ca, ca dépend de ton gameplay, du jeu que tu veux créer et de plein d'aspects que j'ignore pour l'instant

    Ce qui importe, c'est que tu te rendes compte de plusieurs choses:

    1. Tu peux accéder en lecture à tes différentes statistiques parce que cela correspond à certains services que tu es en droit d'attendre de la part de ton personnage
    2. Toute modification des statistiques passe d'office par l'appel d'un comportement spécifique de ton personnage
    3. Certains comportements de ton personnages peuvent être publics parce que ce sont des services que l'on est en droit d'attendre de sa part, d'autres ne sont que des "comportements internes" dont on n'a pas à s'occuper ailleurs qu'au niveau des différentes fonctions membres de personnage.
    4. Certains services que tu es en droit d'attendre de la part de ton personnage sont susceptibles, dans certaines circonstances, d'appeler d'autres comportements ou d'autres services, voire de modifier les statistiques de ton personnage.
    Tu dois donc penser à ton personnage en termes de services que tu es en droit d'attendre de sa part, et non en termes de données qu'il manipule.

    Les données qu'il manipulent sont, typiquement des "détails d'implémentation" qui permettent au personnage de rendre les services que l'on est en droit d'attendre de sa part

    Ainsi, j'aurais très bien pu regrouper tous les int dans un seul tableau, cela n'aurait rien changé pour l'utilisateur de la classe Personnage (même ca aurait changé le code pour accéder aux différentes stats au niveau des fonctions membres de Personnage )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    Si si je suis très bien et je suis tout à fait d'accord tout ça été prévu c'est juste le fait qu'il y ait autant attribut car j'ai eu l'habitude de faire des classes avec 4-5 attributs privés max et là il y en a une dizaine du coup je ne savais pas si c'était vraiment bien d'en avoir autant en général quand j'en ai autant j'utilise des structures c'est cela qui me perturbait c'est tout après sur le reste ça je suis tout à fait d'accord avec toi.

  6. #6
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    par ailleurs pour les monstres j'ai fait comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<int, SMonstre> monstre;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct SMonstre {
            SMonstre(std::string nom, int hp, int mp, std::string type, int exp, int gold):
                nom(nom), hp(hp), mp(mp), type(type), exp(exp), gold(gold){}
     
        std::string nom;
        int hp;
        int mp;
        std::string type;
        int exp;
        int gold;
     
    };
    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
    void chargemonstre(SMap & Map, string filename, int index)
    {
        cout << "chargement monstre" << endl;
     
        ifstream ifs(filename);
        int ligne = 0;
        while(!ifs.eof())
        {
            char c = ifs.get();
            if(c == '\n')
            {
                ligne++;
            }
        }
        //cout << "ligne " << ligne << endl;
     
        /*std::tr1::mt19937 gen(time(0));
        std::tr1::uniform_int <int> a(1,ligne);
        int lignechoisi = a(gen);*/
        //srand(time(0));
        int lignechoisi  = 0;
        lignechoisi = (rand() % ligne);
        cout << "ligne choisi " << lignechoisi << endl;
       /* ifs.clear();
        ifs.seekg(0, ios::beg);
        int pos = ifs.tellg();
        cout << "position " << pos << endl;*/
        ifs.close();
        ifs.open(filename);
    //    ifstream ifs(filename);
        //lignechoisi--;
        while(lignechoisi > 0)
        {
            //cout << "entrer 2eme boucle" << endl;
            char c = ifs.get();
            //cout << c << endl;
            if(c == '\n')
            {
                //cout << c << " trouver" << endl;
                lignechoisi--;
                //cout << "ligne " << lignechoisi << endl;
            }
            /*string nom;
            getline(ifs, nom);
            lignechoisi--;
            cout << nom << endl;*/
        }
     
        string nom;
        int hp;
        int mp;
        string type;
        int exp;
        int gold;
        //cout << "remplissage" <<  endl;
        ifs>>nom>>hp>>mp>>type>>exp>>gold;
     
        //cout << nom << " " << hp << " " << mp << " " <<
        //        type << " " << exp << " " << gold << endl;
        //cout << "fin remplissage" << endl;
        //Map.monstre.insert(std::make_pair(Position(joueur.x(), joueur.y()), SMonstre(nom, hp, mp, type, exp, gold)));
        Map.monstre.insert(std::make_pair(int(index), SMonstre(nom, hp, mp, type, exp, gold)));
    }
    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
    else if(Map.tileAt(joueur.x(), joueur.y()) == 'M')
               {
                   Map.monstre.clear();
                   srand(time(NULL));
                   int nbmonstre = 0;
                   while(nbmonstre == 0)
                   {
                       nbmonstre = rand() % 5;
                   }
                   string filename = Map.title + "_monstre" + ".txt";
                   cout << "nombre monstre " << nbmonstre << " " << "nom fichier " << filename << endl;
                   for(int i = 0; i < nbmonstre; i++)
                   {
                       chargemonstre(Map, filename, i);
                   }
     
                   for(int i = 0; i < nbmonstre; i++)
                   {
                       cout << "monstre " << i <<endl;
                      auto it = Map.monstre.find(i);
                   cout << it->second.nom << " " << it->second.hp <<" "<< it->second.mp << " " <<
                           it->second.type << " " << it->second.exp << " " << it->second.gold << endl;
                   }
               }
    est ce bien ? car maintenant que je vois mieux je me demande si c'est pas mieux de passer par une class monstre

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par devdeb91 Voir le message
    si si je suis trés bien et je suis tout a fait d'accord tout sa été prevue c'est juste le fait qu'il est autant attribut car j'ai eu l'habitude de faire des class avec 4-5 attribut privé max et la y en a une dizaine du coup je ne savais pas si c'était vraiment bien d'en avoir autant en général quand j'en est autant j'utilise des structure c'est cela qui me perturber c'est tout aprrés sur le reste sa je suis tout a fait d'accord avec toi.
    Oh, il y aurait effectivement moyen de passer par des interfaces et par l'héritage multiple pour éviter d'avoir trop d'attributs dans ta classe Personnage (ce pourrait d'ailleurs être conseillé ), mais cela reviendrait au final à peu près au même .

    Ceci dit, il faut te dire que les différents attributs de ta classe ne sont là que pour permettre à ta classe de fournir les services que l'on en attend.

    Dans le cadre d'un personnage de jeu, on s'attend à ce qu'il fournisse un grand nombre de services, il n'est donc pas étonnant outre mesure qu'il soit composé... d'un nombre important d'attributs
    Citation Envoyé par devdeb91 Voir le message
    par ailleurs pour les monstres j'ai fait comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<int, SMonstre> monstre;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct SMonstre {
            SMonstre(std::string nom, int hp, int mp, std::string type, int exp, int gold):
                nom(nom), hp(hp), mp(mp), type(type), exp(exp), gold(gold){}
     
        std::string nom;
        int hp;
        int mp;
        std::string type;
        int exp;
        int gold;
     
    };
    Avoir une chaine de caractères pour le type, c'est moyen moyen...

    Et ce ne serait qu'à peine mieux si tu décidais de remplacer cette chaine par une valeur énumérée.

    Le fait est que, si tu as plusieurs types de monstres possibles, tu devrais envisager de créer une classe de base Monstre, et une classe dérivée de Monstre par type de monstre que tu envisage de créer.

    Pour manipuler un monstre d'un type donné comme étant de son type particulier et non du type Monstre, il faudrait alors passer par le double dispatch.

    Evidemment, cela signifie que tu devrais utiliser une map de type <int, Monstre * > (ou mieux, basée sur un pointeur intelligent), et qu'il faudrait sans doute avoir recours au patron de conception Fabrique, histoire que le système de gestion des monstres n'aie pas à connaitre l'ensemble des différents types de monstres existants
    est ce bien ?
    C'est largement perfectible
    car maintenant que je vois mieux je me demande si c'est pas mieux de passer par une class monstre
    En fait, à bien y regarder, il y a de nombreux points communs entre les monstres et le personnage (d'ailleurs, dans quelle mesure ne pourrait on pas envisager le fait qu'un monstre n'est jamais qu'un personnage particulier )

    On pourrait donc assez facilement en arriver à la conclusion qu'il est possible de regrouper dans la classe personnage ce qui est commun aux monstres et à ce que l'on appelle pour l'instant personnage, et d'avoir une classe "joueur" et une classe "monstre" qui prendraient en charge ce qui est spécifique à ces deux types distincts.

    Quand je te disais, lorsque tu a émis l'idée de créer un jeu, qu'il fallait vraiment commencer par réfléchir à tes besoins et au fait que ceux ci allaient évoluer afin de ne pas te retrouver bloqué sur une évolution
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    alors voila j'ai créer mes 2 class mais un probleme est detecter

    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
    #ifndef MONSTRE_H_INCLUDED
    #define MONSTRE_H_INCLUDED
    #include <string>
    #include "main.h"
    #include "personnage.h"
     
     
    class monstre
    {
        private:
     
            std::string m_nom;
            int m_hp;
            int m_mp;
            std::string m_type;
            int m_xp;
            int m_argent;
     
        public:
     
            monstre(std::string nom, int hp, int mp, std::string type, int xp, int argent):m_nom(nom), m_hp(hp), m_mp(mp),
                m_type(type), m_xp(xp), m_argent(argent){}
            ~monstre()
            {
     
            }
            void attaquer(personnage &cible)
            {
                cible.recevoir_degats(50);
            }
            void recevoir_degats(int nbdegats)
            {
                m_hp -= nbdegats;
                if(m_hp < 0)
                    m_hp = 0;
            }
            bool est_vivant()
            {
     
                if(m_hp > 0)
                    return true;
                else
                    return false;
            }
    };
     
    #endif // MONSTRE_H_INCLUDED
    il me dis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    C:\Users\kevin\Desktop\jeu2\monstre.h|27|error: 'personnage' has not been declared|
    C:\Users\kevin\Desktop\jeu2\monstre.h||In member function 'void monstre::attaquer(int&)':|
    C:\Users\kevin\Desktop\jeu2\monstre.h|29|error: request for member 'recevoir_degats' in 'cible', which is of non-class type 'int'|
    ||=== Build finished: 2 errors, 0 warnings (0 minutes, 1 seconds) ===|
    alors que je lui dis bien d'aller prendre personnage.h donc auriez vous une idée de se qu'il veut

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Si tu as suivi les conseils de Koala01, je suppose que tu as mis une majuscule à Personnage, majuscule que tu n'aurais pas reporté dans monstre.h ?

    Sinon, prend bien l'habitude de mettre des majuscules à tes classes pour éviter de les confondre avec des variables.

    Si ce n'est pas le cas, pourrais-tu nous montrer ton personnage.h?

  10. #10
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    Non pas mis bien que je le fait d'habitude.

    voici le personnage.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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #ifndef PERSONNAGE_H_INCLUDED
    #define PERSONNAGE_H_INCLUDED
    #include "main.h"
    #include "monstre.h"
    //#include "arme.h"
     
    class personnage
    {
        private:
     
            int m_hp;
            int m_pm;
            int m_xp;
            int m_or;
            //arme m_arme;
     
        public:
     
            personnage(): m_hp(1000), m_pm(20), m_xp(0), m_or(500){}
            ~personnage()
            {
     
            }
            void recevoir_degats(int nombre_degats)
            {
                m_hp -= nombre_degats;
                if(m_hp < 0)
                    m_hp = 0;
            }
            //void soin(int nombre_soin);
            void attaquer(monstre &cible)
            {
                cible.recevoir_degats(15);
            }
            //void magie(personnage &cible);
            //void objet(std::string nom);
            bool est_vivant()
            {
     
                if(m_hp > 0)
                    return true;
                else
                    return false;
            }
            void recevoir_gain(int xp, int argent)
            {
                m_xp = m_xp + xp;
                m_or = m_or + argent;
            }
     
    };
     
    #endif // PERSONNAGE_H_INCLUDED

  11. #11
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Tu va être obligé d'utiliser des déclarations anticipée pour éviter les dépandances cycliques :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class A;
     
    class B
    {
          A * a;
    }
     
    class A
    {
          B * b;
    }
    Soit dans un .h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Personnage;
     
     
    class Monstre{}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Monstre;
     
    class Personnage{}

  12. #12
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    ok bah j'essaye ça merci. par contre comment faire car une des deux classes utilise personnage et l'autre monstre donc l'une ne verra pas la classe de l'autre vue qu'elle sera après et donc ne pourra pas déclarer l'objet

  13. #13
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Pourtant avec mes classes A et B je n'ai eu aucun problème.
    Pour mon second exemple je n'ai pas mis un Monstre * dans Personnage et un Personnage * dans Monstre mais c'est tout comme.

  14. #14
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    Il me dit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    C:\Users\kevin\Desktop\jeu2\monstre.h||In member function 'void monstre::attaquer(personnage&)':|
    C:\Users\kevin\Desktop\jeu2\monstre.h|30|error: invalid use of incomplete type 'class personnage'|
    C:\Users\kevin\Desktop\jeu2\monstre.h|7|error: forward declaration of 'class personnage'|
    ||=== Build finished: 2 errors, 0 warnings (0 minutes, 1 seconds) ===|
    je pense avoir fait comme tu as dis

    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
    #ifndef MONSTRE_H_INCLUDED
    #define MONSTRE_H_INCLUDED
    #include <string>
    #include "main.h"
    //#include "personnage.h"
     
    class personnage;
     
    class monstre
    {
        private:
     
            std::string m_nom;
            int m_hp;
            int m_mp;
            std::string m_type;
            int m_xp;
            int m_argent;
     
        public:
     
            monstre(std::string nom, int hp, int mp, std::string type, int xp, int argent):m_nom(nom), m_hp(hp), m_mp(mp),
                m_type(type), m_xp(xp), m_argent(argent){}
            ~monstre()
            {
     
            }
            void attaquer(personnage &cible)
            {
                cible.recevoir_degats(50);
            }
            void recevoir_degats(int nbdegats)
            {
                m_hp -= nbdegats;
                if(m_hp < 0)
                    m_hp = 0;
            }
            bool est_vivant()
            {
     
                if(m_hp > 0)
                    return true;
                else
                    return false;
            }
    };
     
    #endif // MONSTRE_H_INCLUDED
    j'ai aussi tester sa

    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
    90
    91
    92
    93
    94
    95
    96
    #ifndef PERSONNAGE_H_INCLUDED
    #define PERSONNAGE_H_INCLUDED
    #include "main.h"
    #include <string>
    //#include "monstre.h"
    //#include "arme.h"
     
    class monstre;
     
    class personnage
    {
        private:
     
            int m_hp;
            int m_pm;
            int m_xp;
            int m_or;
            //arme m_arme;
     
        public:
     
            personnage(): m_hp(1000), m_pm(20), m_xp(0), m_or(500){}
            ~personnage()
            {
     
            }
            void recevoir_degats(int nombre_degats)
            {
                m_hp -= nombre_degats;
                if(m_hp < 0)
                    m_hp = 0;
            }
            //void soin(int nombre_soin);
            void attaquer(monstre &cible)
            {
                cible.recevoir_degats(15);
            }
            //void magie(personnage &cible);
            //void objet(std::string nom);
            bool est_vivant()
            {
     
                if(m_hp > 0)
                    return true;
                else
                    return false;
            }
            void recevoir_gain(int xp, int argent)
            {
                m_xp = m_xp + xp;
                m_or = m_or + argent;
            }
     
    };
     
    class monstre
    {
        private:
     
            std::string m_nom;
            int m_hp;
            int m_mp;
            std::string m_type;
            int m_xp;
            int m_argent;
     
        public:
     
            monstre(std::string nom, int hp, int mp, std::string type, int xp, int argent):m_nom(nom), m_hp(hp), m_mp(mp),
                m_type(type), m_xp(xp), m_argent(argent){}
            ~monstre()
            {
     
            }
            void attaquer(personnage &cible)
            {
                cible.recevoir_degats(50);
            }
            void recevoir_degats(int nbdegats)
            {
                m_hp -= nbdegats;
                if(m_hp < 0)
                    m_hp = 0;
            }
            bool est_vivant()
            {
     
                if(m_hp > 0)
                    return true;
                else
                    return false;
            }
    };
     
     
    #endif // PERSONNAGE_H_INCLUDE
    même erreur dans les deux cas

  15. #15
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Je ne t'ai donné la solution que pour les header.

    Ensuite il faut inclure les header personnage.h et monste.h dans les deux .cpp


    EDIT : pense aussi à mettre le corps des méthodes dans les .cpp

  16. #16
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    bah j'ai inclus dans les cpp mais ça me met l'erreur quoi qu'il arrive si tu veux je joins tout le code entier mais je suis pas sur que ça serve

  17. #17
    Membre émérite

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Billets dans le blog
    1
    Par défaut
    Je pense que Nekara te parles de ce qui est expliqué ici http://cpp.developpez.com/faq/cpp/?p...erence_croisee

  18. #18
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    Merci du lien celui ci je ne l'avais pas trouvé mais comment faire dans le cadre de 2 .h sans cpp car j'ai pris l'habitude de faire comme koala c'est à dire de mettre tout dans les .h et pas faire de .cpp du coup sa pose problème

  19. #19
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Je doute fortement que Koala01 ait l'habitude de tout mettre dans le .h, c'est juste que c'est plus facile/pratique quand on veut montrer des petits exemples sur le forum ou expliquer quelque chose.

    @PilloBuenaGente : Oui c'est cela merci.
    Je dois avouer que c'est un peu de ma faute de ne pas tout avoir expliqué dès le début .

  20. #20
    Membre éclairé Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Par défaut
    Je n'ai pas dis qu'il avait cette habitude j'ai dit que j'ai pris l'habitude de faire comme lui (en gros comme ce qu'il ma montré) désolé si je me suis mal exprimé.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Structure ou classe ?
    Par progfou dans le forum C++
    Réponses: 5
    Dernier message: 01/10/2007, 14h27
  2. Schéma structure des classes
    Par delma dans le forum EDI et Outils pour Java
    Réponses: 8
    Dernier message: 29/11/2006, 16h52
  3. [log4j] structurer par classes
    Par frouge dans le forum Logging
    Réponses: 4
    Dernier message: 25/09/2006, 11h24
  4. Structure de classe dynamique
    Par amel666 dans le forum Langage
    Réponses: 2
    Dernier message: 24/01/2006, 09h13
  5. structure de class?
    Par kiko69 dans le forum C++
    Réponses: 4
    Dernier message: 13/03/2005, 14h30

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