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

Langage C++ Discussion :

problème polymorphisme (je crois) et héritage


Sujet :

Langage C++

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Musicien amateur
    Inscrit en
    mars 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 15
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Musicien amateur

    Informations forums :
    Inscription : mars 2018
    Messages : 16
    Points : 7
    Points
    7
    Par défaut problème polymorphisme (je crois) et héritage
    Bonjour, je suis en train de développer un genre de sim city simplifié.

    classes: energy->building, RCI->building

    Pour stocker les batiments, j'ai créé un vector de vector qui contiennent des références de buildings pour que puisse mettre la classe energy ou RCI dans le meme tableau.
    Je peux utiliser les fonctions de building mais pas les fonctions de Energy quand j'insere un Energy dans le vector... Comment puis-je faire pour que l'objet de la classe energy soit considérée comme un energy?

    Merci d'avance pour vos réponses !

    Main.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
     
    std::vector<building*> batiments[17];
     
     
    void listBatiments();
     
     
    int main()
    {
     
        listBatiments();
        return 0;
    }
     
    void listBatiments(){
        batiments[0].push_back(new Energy(Energy::power));
     
     
        batiments[0][0]->setAllProperties(6000, 150, 3,3, "Coal power plant", 17);
        batiments[0][0]->setState(building::isHud);
        /**
        batiments[0][0]->setEnergyDelivered(1000);
        
        ça ne marche pas
        error: 'class building' has no member named 'setEnergyDelivered'|
        **/
    }
    energy.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
     
    #ifndef ENERGY_H
    #define ENERGY_H
     
    #include <building.h>
     
     
    class Energy : public building
    {
        public:
            enum energyType{water,power,garbage};
     
     
            Energy(energyType energy);
            ~Energy();
     
     
            void setEnergyDelivered(int energyDelivered);
            int getEnergyDelivered();
     
     
        private:
            energyType m_energyType;
            int m_energyDelivered;
    };
     
     
    #endif // ENERGY_H

  2. #2
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    3 886
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 3 886
    Points : 8 695
    Points
    8 695
    Par défaut
    Il faut tester , mais
    1. soit les fonctions doivent être virtuelles dans la classe Building (<- avec 1 B majuscule parce que tes conventions de codage/ ton code sont très "à la one again bistoufly" )
    2. soit tu castes Energy* elt = (Energy*) batiments[0][0]; elt->setEnergyDelivered(1000);

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Musicien amateur
    Inscrit en
    mars 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 15
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Musicien amateur

    Informations forums :
    Inscription : mars 2018
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par foetus Voir le message
    Il faut tester , mais
    1. soit les fonctions doivent être virtuelles dans la classe Building (<- avec 1 B majuscule parce que tes conventions de codage/ ton code sont très "à la one again bistoufly" )
    2. soit tu castes Energy* elt = (Energy*) batiments[0][0]; elt->setEnergyDelivered(1000);
    Merci pour ta réponse, pour le B ça a été changé.

    comme je n'ai pas les mêmes fonctions dans Building et Energy, les méthodes virtuelles ne servent à rien et ne changent rien. ça m'embète un peu de devoir à chaque fois déclarer une variable mais si c'est la seule solution je vais devoir faire avec.

  4. #4
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    3 886
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 3 886
    Points : 8 695
    Points
    8 695
    Par défaut
    Citation Envoyé par blue dragon Voir le message
    je n'ai pas les mêmes fonctions dans Building et Energy, les méthodes virtuelles ne servent à rien et ne changent rien
    Tu en es sûr ? Si tu déplaces ta méthode setEnergyDelivered dans la classe Building en la mettant virtuelle, je pense que tu n'as pas besoin de caster et que juste batiments[0][0]-> fonctionne.

    Après effectivement, la conception c'est n'importe quoi tu ne peux pas garnir ta classe mère avec les fonctions des classes filles il y a sûrement 1 autre façon de concevoir le code.


    Édit : Lorsque je dis déplacer , c'est la déclarer dans la classe Building en virtuelle pour être ensuite surchargée dans la classe Energy (<- avec la même implémentation).
    Mais effectivement, c'est l'implémentation dans la classe Building qui pose question

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Musicien amateur
    Inscrit en
    mars 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 15
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Musicien amateur

    Informations forums :
    Inscription : mars 2018
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par foetus Voir le message
    Tu en es sûr ? Si tu déplaces ta méthode setEnergyDelivered dans la classe Building en la mettant virtuelle, je pense que tu n'as pas besoin de caster et que juste batiments[0][0]-> fonctionne.

    Après effectivement, la conception c'est n'importe quoi tu ne peux pas garnir ta classe mère avec les fonctions des classes filles il y a sûrement 1 autre façon de concevoir le code.
    ça peut marcher mais que si je met la méthode dans Buildings ce qui n'est pas pratique au vu du nombre de classes que j'aimerais faire.

  6. #6
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2011
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2011
    Messages : 697
    Points : 3 371
    Points
    3 371
    Par défaut
    L'utilisation de l'héritage n'est peut-être tout simplement pas la bonne manière de faire. Pourquoi ne pas faire un std::vector par type ?

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Musicien amateur
    Inscrit en
    mars 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 15
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Musicien amateur

    Informations forums :
    Inscription : mars 2018
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par jo_link_noir Voir le message
    L'utilisation de l'héritage n'est peut-être tout simplement pas la bonne manière de faire. Pourquoi ne pas faire un std::vector par type ?
    Tout simplement parce que je compte mettre une trentaine de batiments différents et je ne vais pas faire 30 for pour chaque action à faire mais plutot 1 for dans 1 for pour tout

  8. #8
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2011
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2011
    Messages : 697
    Points : 3 371
    Points
    3 371
    Par défaut
    Il y a des moyens simples pour ne pas écrire les 30 for avec plusieurs vector: std::tuple + std::apply.

  9. #9
    Membre expérimenté Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    mai 2007
    Messages
    913
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : mai 2007
    Messages : 913
    Points : 1 742
    Points
    1 742
    Par défaut
    Sinon, tu changes ton approche et tu préfères l'agrégation à l'héritage ( ce qui est fait dans 95÷ de l'industrie du jeu vidéo pour ces raisons).
    Ton bâtiments peut contenir une liste de propriété en fonction de son type ( Énergie, Eau, logements, etc...) tu verras que ça peut te permettre des trucs du genre un bâtiment qui créer de l'énergie et de l'eau et loge des gens aussi... )

    Personnellement, quand je vois plus d'un niveau d'héritage je me met à souffler devant mon écran :p)
    Homer J. Simpson


  10. #10
    Membre habitué Avatar de Suryavarman
    Homme Profil pro
    Développeur 3D
    Inscrit en
    mai 2006
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur 3D
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : mai 2006
    Messages : 193
    Points : 184
    Points
    184
    Par défaut
    Hormis les problèmes de choix d'architectures cité précédemment.
    Si ton soucis est dans cette fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void listBatiments(){
        batiments[0].push_back(new Energy(Energy::power));
     
     
        batiments[0][0]->setAllProperties(6000, 150, 3,3, "Coal power plant", 17);
        batiments[0][0]->setState(building::isHud);
        /**
        batiments[0][0]->setEnergyDelivered(1000);
        
        ça ne marche pas
        error: 'class building' has no member named 'setEnergyDelivered'|
        **/
    }
    Alors applique tout tes paramètres à l'instance de l'objet plutôt que de passer par le conteneur. Autrement dit applique lui les paramètres souhaités avant de l'envoyer dans le conteneur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void listBatiments(){
        auto energy = new Energy(Energy::power);
     
        energy ->setAllProperties(6000, 150, 3,3, "Coal power plant", 17);
        energy->setState(building::isHud);
        energy->setEnergyDelivered(1000);
     
        batiments[0].push_back(energy);
    }
    Quand tu fais setEnergyDelivered c'est parce-que tu es sûr que c'est de l'énergie. Sans trop te casser la tête pour débuter tu peux faire un dynamic_cast et si c'est pas nulle tu fais un setEnergy. Par contre c'est pas beau :p.
    "Quand le monde est dangereux, l'humilité est un facteur de longévité." ( Baxter "Evolution" )

Discussions similaires

  1. Réponses: 8
    Dernier message: 18/06/2007, 15h06
  2. problème au niveau de l'héritage, ou autre chose
    Par lotus0o dans le forum Langage
    Réponses: 5
    Dernier message: 04/06/2007, 11h54
  3. [MySQL] problème de requête croisé?
    Par gotcha5832 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 21/03/2007, 19h11
  4. [Hibernate]Problème pour mapping d' un héritage
    Par K-Kaï dans le forum Hibernate
    Réponses: 6
    Dernier message: 29/06/2006, 14h28
  5. Réponses: 2
    Dernier message: 25/07/2004, 23h24

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