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 :

Problème avec mon héritage


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Par défaut Problème avec mon héritage
    Bonjour a toutes et tous, je reviens vers vous encore une fois (et normalement c'est la dernière, promis ).

    Je suis un train de développer un mini RPG pour appliquer ce que j'ai appris sur le c++ et j'ai un petit souci qui mélange polymorphisme et héritage. En gros mon idée de RPG est un duel de mage, on choisi le nom de son mage et son type (feu, glace, eau, etc ...) et puis on se lance dans la bataille (chaque mage à des sorts spécifiques à son type).

    Pour l'instant j'en suis à: une classe mère nommé Mage qui me sert de base pour tous les mages, me permettant ainsi d'initialiser des points de vie, les points de mana, le traitement des dégâts, les gain ou perte de points de vie et de mana, etc ...

    Voici les fichiers .h et .cpp pour vous donner l'idée
    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
     
    #ifndef MAGE_H_INCLUDED
    #define MAGE_H_INCLUDED
     
    #include <iostream>
    #include <vector>
    #include <string>
     
    class Mage
    {
        public:
            //Constructeur
            Mage(std::string nom);
     
            //Destructeur
            virtual ~Mage();
     
            //Methodes
            virtual void recevoirDegats(int degats);
            virtual void perteMana(Mage &cible, int pmana);
            virtual void gainMana();
            virtual void boirePotion();
            virtual void attaqueBase(Mage &cible) const;
            virtual void sePresenter () const;
            virtual void afficherEtat() const;
            virtual int etatVie();
     
        protected:
            //Attributs
            int m_vie;
            int m_mana;
            std::string m_nom;
    };
     
    #endif // PERSONNAGE_H_INCLUDED
    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
     
    #include "Mage.h"
     
    using namespace std;
     
     
    //Constructeur
    Mage::Mage(string nom) : m_vie(100), m_mana(100), m_nom(nom)
    {
     
    }
     
    //Destructeur
    Mage::~Mage()
    {
     
    }
     
     
    //Méthode "de base" pour tous les personnes
    void Mage::recevoirDegats(int degats)
    {
        m_vie -= degats;
    }
     
    void Mage::perteMana(Mage &cible, int pmana)
    {
        m_mana -= pmana;
    }
     
    void Mage::boirePotion()
    {
        m_vie += 20;
    }
     
    void Mage::gainMana()
    {
        m_mana += 5;
    }
     
    void Mage::attaqueBase(Mage &cible) const
    {
        cible.recevoirDegats(10);
    }
     
    void Mage::sePresenter() const
    {
        cout << "Bonjour, je m'appelle " << m_nom << "." << endl;
        cout << "J'ai encore " << m_vie << " points de vie et " << m_mana << " points de mana." << endl << endl;
    }
     
     
    void Mage::afficherEtat() const
    {
        cout << "Etat de " << m_nom << endl;
        cout << "Vie : " << m_vie << endl;
        cout << "Mana : " << m_mana << endl << endl;
    }
     
    int Mage::etatVie()
    {
        return(m_vie);
    }
    Puis (pour l'instant), j'ai créé un mage de type feu qui hérite de ma classe mère Mage nommé MageFeu dont voici les fichiers .h et .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
     
    #ifndef MAGEFEU_H_INCLUDED
    #define MAGEFEU_H_INCLUDED
     
    #include <iostream>
    #include <string>
    #include "Mage.h"
     
    class MageFeu : public Mage
    {
        public:
            //Constructeurs
            MageFeu(std::string nom);
     
            //Destructeur
            virtual ~MageFeu();
     
            //Methodes
            virtual void sePresenter () const;
            virtual void bouleDeFeu(Mage &cible) const;
     
        protected:
            //Attributs spécifiques a la classe Magicien
     
    };
     
    #endif // MAGEFEU_H_INCLUDED
    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
     
    #include "Mage.h"
    #include "MageFeu.h"
     
    using namespace std;
     
    //Constructeurs
    MageFeu::MageFeu(string nom) : Mage(nom)
    {
     
    }
     
    //Destructeur
    MageFeu::~MageFeu()
    {
     
    }
     
     
    //Méthodes spécifiques à la classe Mage de feu
    void MageFeu::sePresenter() const
    {
        cout << "Bonjour, je m'appelle " << m_nom << ". Je suis un Mage de feu" << endl;
        cout << "J'ai encore " << m_vie << " points de vie et " << m_mana << " points de mana." << endl << endl;
    }
     
     
    void MageFeu::bouleDeFeu(Mage &cible) const
    {
        cible.recevoirDegats(35);
    }
    Dans mon main maintenant, je gère la création de mes deux personnages mais ne sachant pas de quel type ils sont (vu que c'est au joueur de choisir) j'utilise le polymorphisme avec le code suivant:

    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
     
    string nomMage1;
        string nomMage2;
        int choixType1(0);
        int choixType2(0);
     
        //Creation du premier mage
        Mage* pMage1 = NULL;
    	cout << "Rentrez le nom du premier mage svp:" << endl;
    	getline(cin, nomMage1);
    	cout << "Choisissez le type de mage:" << endl;
    	cin >> choixType1;
    	if(choixType1 == 1)
    	{
    		pMage1 = new Mage(nomMage1);
    	}
    	else if(choixType1 ==2)
    	{
    		pMage1 = new MageFeu(nomMage1);
    	}
        pMage1->sePresenter();
        std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
     
        //Creation du deuxième mage
        Mage* pMage2 = NULL;
    	cout << "Rentrez le nom du deuxieme mage svp:" << endl;
    	getline(cin, nomMage2);
    	cout << "Choisissez le type de mage:" << endl;
    	cin >> choixType2;
    	if(choixType2 == 1)
    	{
    		pMage2 = new Mage(nomMage2);
    	}
    	else if(choixType2 ==2)
    	{
    		pMage2 = new MageFeu(nomMage2);
    	}
        pMage2->sePresenter();
    Jusqu'ici, je ne rencontre aucun problème, la création de mes personnes se fait bien et ils sont bien du type choisi (vérification faite avec la méthode sePresenter()).

    C'est après que j'ai un problème dans ma boucle de comabt (pour l'instant la boucle n'est pas implémentée) dont voici le code:

    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
     
    int choixAction1(0);
        //int choixAction2(0);
        int choixAttaque1(0);
        //int choixAttaque2(0);
        int compteurTour(1);
     
        //int etatVie1(0);
        //int etatVie2(0);
     
        cout << "TOUR " << compteurTour << endl << endl;
        cout << nomMage1 << ", choisissez l'action a effectuer" << endl;
        cin >> choixAction1;
        switch(choixType1)
        {
            case 1:
                switch(choixAction1)
                {
                    case 1:
                        cout << nomMage1 << ", a vous d'attaquer. Veuillez choisir une attaque entre:" << endl << "1 - Attaque de base" << endl;
                        cin >> choixAttaque1;
                    break;
                    default:
     
                    break;
                }
            break;
            case 2:
                   switch(choixAction1)
                {
                    case 1:
                        cout << nomMage1 << ", a vous d'attaquer. Veuillez choisir une attaque entre:" << endl << "1 - Attaque de base" << endl << "2 - Boule de Feu" << endl;
                        cin >> choixAttaque1;
                        switch(choixAttaque1)
                        {
                            case 1:
                                pMage1->attaqueBase(*pMage2);
                            break;
                            case 2:
                                pMage1->bouleDeFeu(*pMage2);
                                pMage1->perteMana(*pMage1, 5);
                            break;
                            default:
     
                            break;
                        }
                    break;
                    default:
     
                    break;
                }
        }
    Alors, déjà, oui je sais que c'est un peu une usine à gaz (comme on dit par chez moi) mais pour l'instant je n'ai pas d'autre idée de syntaxe donc veuillez me pardonner.

    Mon problème viens de la ligne de code suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pMage1->bouleDeFeu(*pMage2);
    qui me génère comme erreur
    "error: 'class Mage' has no member named 'bouleDeFeu' "

    Alors l'erreur je l'a comprend, ma classe Mage (donc ma classe mère ne connait pas la méthode bouleDeFeu, cette erreur doit très probablement venir du fait que lorsque je crée un personnage j'ai cette ligne de code
    (on utilise le constructeur de la classe mère)

    Donc ma question est: est-ce que je dois la faire version méga-bourrin (enfin je pense) où je déclare toutes les méthodes de sorts (quelque soit le type) dans la classe mère et après j'adapte dans mes switchs en fonction du type choisi par le joueurs ou alors est-ce qu'il y a un moyen de garder les méthodes dans les classes filles ?

    Dans l'attente de vos réponses,
    Cordialement,
    Clairetj

  2. #2
    Membre expérimenté
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 227
    Par défaut
    Comme tu as déclaré un pointeur sur la classe mère, il est normal que tu ne puisses accéder à une méthode de la classe fille qui est inexistante dans la classe mère.
    Cependant comme tu sais de quel type est ton mage puisque tu appels une méthode spécifique d'une classe fille, il te suffit dans ton switch de faire un cast dynamique de ton pMage vers le type de mage que tu as implémenté.
    Dés lors, la méthode sera connue.

  3. #3
    Membre éclairé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Par défaut
    Donc si je comprend bien ce que tu m'explique, dans mon switch où j'appelle la méthode bouleDeFeu qui appartient à une classe fille je doit mettre avant la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pMage1 = dynamic_cast<MageFeu*>(pMage1);
    donc cela donnerait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pMage1 = dynamic_cast<MageFeu*>(pMage1);
    pMage1->bouleDeFeu(*pMage2);                       
    pMage1->perteMana(*pMage1, 5);

  4. #4
    Membre expérimenté
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 227
    Par défaut
    Non, pas tout à fait. pMage et de type Mage* est ça tu ne peux pas le changer tu dois faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    dynamic_cast<MageFeu*>(pMage1)->BouleDefeu( *pMage2);
    ou bien tu déclare un nouveau pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MageFeu *pMageFeu = dynamic_cast<MageFeu*>(pMage1);
    et après tu utilises pMageFeu dans ton switch.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 227
    Par défaut
    Si tu veux éviter ce type de manipulation, tu peux aussi déclarer dans ta classe mère une méthode virtuelle pure "attaque" qui prend un paramètre de type entier, et c'est cette méthode que tu surcharges dans les classes filles dès lors tu n'as plus à t’embêter avec les histoires de cast.

  6. #6
    Membre éclairé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Par défaut
    Merci AF_2.8

    J'ai choisi d'utiliser la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MageFeu *pMageFeu = dynamic_cast<MageFeu*>(pMage1);
    et donc utiliser pMageFeu dans le reste du switch et cela marche tel que je le souhaitais,

    Encore merci pour ton aide

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

Discussions similaires

  1. [VC++] Problème avec un héritage
    Par Freakazoid dans le forum Visual C++
    Réponses: 7
    Dernier message: 28/11/2005, 08h35
  2. [DEBUTANT] Probléme avec l'héritage
    Par BRAUKRIS dans le forum Langage
    Réponses: 7
    Dernier message: 16/09/2005, 20h22
  3. Problème avec mon service mysql et PhpMyAdmin
    Par Fixazo dans le forum Outils
    Réponses: 1
    Dernier message: 28/08/2005, 18h02
  4. problème avec mon lecteur CD
    Par leo13 dans le forum Périphériques
    Réponses: 3
    Dernier message: 16/08/2005, 11h21
  5. Problème avec mon firewall ...
    Par Wis dans le forum Tomcat et TomEE
    Réponses: 15
    Dernier message: 06/04/2004, 08h46

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