Partage
  • Partager sur Facebook
  • Partager sur Twitter

Attribut de classe : Initialisation

Sujet résolu
    4 juin 2019 à 21:32:41

    Bonjour!

    Je sais que le titre n'est pas très parlant, je m'explique : j'ai une classe "Player" qui doit posséder 2 objet "AnimationSprite"...OR : je ne veux pas que cette classe soit initialisé dans la classe mère mais dans la classe filles de Player, à savoir "Hydrogen" (Concept concept ^^'). Bien entendu, Player serait "abstraite" dans le sens où elle ne sera jamais instancié. Merci de votre aide!

    • Partager sur Facebook
    • Partager sur Twitter
      5 juin 2019 à 9:45:38

      Lu'!

      Tu donnes un constructeur a ta classe abstraite (avoir une classe abstraite n'interdit pas d'avoir un constructeur) et tu utilises ce constructeur depuis les classes dérivées au moment de la construction.

      • Partager sur Facebook
      • Partager sur Twitter
      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
        5 juin 2019 à 10:36:43

        ça donne un pattern que je n'aime pas, du style

        #include <iostream>
        #include <vector>
        #include <memory>
        
        class AbstractObject{
        public:
            enum Type{
                UNKNOWN,
                TYPE_1,
                TYPE_2,
                TYPE_3
            };
            
            explicit AbstractObject(Type objType = Type::UNKNOWN): m_type(objType) {}
            virtual ~AbstractObject(){}
            
            virtual void do_smthng() = 0;
            
            Type get_type() const {return m_type;}
            
        private:
            Type m_type;
        };
        
        
        
        
        
        class Type1Object : public AbstractObject{
        public:
            explicit Type1Object(): AbstractObject(AbstractObject::Type::TYPE_1) {}
            ~Type1Object() override {}
            
            void do_smthng() override {std::cout << "Objet de type 1 = " << get_type() << std::endl;}
        };
        
        
        
        
        
        class Type2Object : public AbstractObject{
        public:
            explicit Type2Object(): AbstractObject(AbstractObject::Type::TYPE_2) {}
            ~Type2Object() override {}
            
            void do_smthng() override {std::cout << "Objet de type 2 = " << get_type() << std::endl;}
        };
        
        
        
        
        
        
        int main()
        {
            std::vector< std::unique_ptr<AbstractObject> > vec;
            vec.push_back(std::make_unique<Type1Object>());
            vec.push_back(std::make_unique<Type2Object>());
            
            for(auto & ptr : vec){
                ptr->do_smthng();
            }
        }
        



        -
        Edité par romantik 11 juin 2019 à 10:03:15

        • Partager sur Facebook
        • Partager sur Twitter
        Dream on, Dream on, Dream until your dream comes true
          5 juin 2019 à 11:35:11

          Il y a rien dans ce qu'il a décrit qui nécessite ton enum.

          • Partager sur Facebook
          • Partager sur Twitter
          Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
            5 juin 2019 à 11:53:40

            Ben non, il le fait avec ce qu'il veut, je donne juste un exemple qui mets en évidence le mécanisme.
            • Partager sur Facebook
            • Partager sur Twitter
            Dream on, Dream on, Dream until your dream comes true
              10 juin 2019 à 20:48:08

              Je suis désolé mais je ne connais absolument pas la librairie <memory>, et je ne coprend pas un bon 75% du code...Par ailleur, j'ai déjà un constructeur dans ma classe mère, qui est appelé par le constructeur de la classe fille, voici :

              Player::Player(int posX, int posY):m_posX(posX),m_posY(posY),m_mass(0),m_speedX(0),m_speedY(0),m_atomSelect(0),m_speedCoef(1),m_delayQEFreeze(0),m_animationMoving("Texture/Atom/HydrogenStatic.png",320,256,5,4,2),m_animationStatic("Texture/Atom/HydrogenStatic.png",320,256,5,4,2)
              {
              
              }

              Pour le constructeur de la classe mère, et celui de la fille :

              Hydrogen::Hydrogen(int posX, int posY):Player(posX,posY)
              {
                  m_animationMoving=AnimationSprite("Texture/Atom/HydrogenStatic.png",320,256,5,4,2);
                  m_animationStatic=AnimationSprite("Texture/Atom/HydrogenStatic.png",320,256,5,4,2);
              }

              Je suis obligé de "réinitialisé" l'objet m_animationSprite car celui-ci doit obligatoirement être initialisé par le constructeur de la classe mère (D'àpres Code::Block du moins). Le problème c'est qu'ainsi, la fenêtre créée plante et ne répond plus... que faire?


              • Partager sur Facebook
              • Partager sur Twitter
                11 juin 2019 à 10:02:19

                Hmm, j'aurais dû espacer plus entre les classes pour pas que ça fasse pâté, j'édite. Parce qu'il n'y a rien de compliqué, 3 classes avec contructeur/destructeur et 1 fonction membre redéfinie.

                <memory> permet d'utiliser les pointeurs intelligent du standard. Tu devrais les utiliser, ça évite des problèmes des gestions mémoire et ça incite à de meilleurs conceptions (ça force à se poser les bonnes questions sur l'ownership)

                Pas compris pourquoi tu doit réaffecter la même valeur aux propriétés, mais si tu veux construire en initialisant différemment dans la classe fille les animations, tu devrais faire un constructeur de la classe mère qui les prend en paramètre (quitte à le mettre dans l'espace protected)

                • Partager sur Facebook
                • Partager sur Twitter
                Dream on, Dream on, Dream until your dream comes true
                  11 juin 2019 à 15:07:34

                  Disons que concrètement j'ai une classe mère, à savoir "Player", qui possède 2 (ou plus) classes filles (Hydrogen, Nitrogen). La classe "Player" possède plusieurs attribut en protected (float m_posX pour les basiques) mais aussi un attribut AnimationSprite m_animationMoving. OR! celles-ci serons initialisées uniquement dans les classes filles (Car celle-ci n'ont pas les mêmes textures en fonctions de l'objet : Hydrogen ne possède pas les même sprite Sheet que Nitrogen), car TOUT les objets "Hydrogen" aurons le même m_animationMoving, donc la questions serais plutôt : Comment rendre un attribut par défaut?

                  EDIT : Est-ce qu'un élément static m_animationSprite (comme celui-ci sera commun à tous) peu arranger la chose, je ne peux pas essayer de suite donc je demande

                  -
                  Edité par DeveCout 11 juin 2019 à 15:17:28

                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 juin 2019 à 16:44:10

                    DeveCout a écrit:

                    OR! celles-ci serons initialisées uniquement dans les classes filles (Car celle-ci n'ont pas les mêmes textures en fonctions de l'objet : Hydrogen ne possède pas les même sprite Sheet que Nitrogen), car TOUT les objets "Hydrogen" aurons le même m_animationMoving, donc la questions serais plutôt : Comment rendre un attribut par défaut?

                    De la même façon que t'as montré romantik.


                    Tu es peut être un peu effrayé par les Enums et les namespace mais ce n'est rien de très complexe.
                    En un peu plus simplifié :

                    class P
                    {
                    public:
                    	P(int Sprite) : h(Sprite) {};
                    
                    
                    	virtual void DoSmth() = 0;
                    
                    protected:
                    	int h;
                    };
                    
                    
                    
                    class H : P
                    {
                    public:
                    	H() : P(1) {}
                    
                    	void DoSmth() final { std::cout << h << std::endl; };
                    };
                    
                    
                    
                    class N : P
                    {
                    public:
                    	N() : P(7) {}
                    
                    	void DoSmth() final { std::cout << h << std::endl; };
                    };
                    
                    
                    
                    int main() 
                    {
                    	H Hydrogen;
                    	//Derrière : 
                    	// H(1) --> P(1) --> h = 1
                    
                    	Hydrogen.DoSmth(); //Print 1
                    
                    	N Nitrogen;
                    	//Derrière : 
                    	// H(7) --> P(7) --> h = 7
                    
                    	Nitrogen.DoSmth(); //Print 7
                    
                    	return 0;
                    }

                     Les constructeurs de H et N appellent toujours le constructeur de P mais lui fourni une valeur différente.

                    DeveCout a écrit:

                    EDIT : Est-ce qu'un élément static m_animationSprite (comme celui-ci sera commun à tous) peu arranger la chose, je ne peux pas essayer de suite donc je demande

                    Non, les membres static sont indépendants des instances de classe.
                    Dans ton cas, tu souhaites justement avoir des valeurs différentes pour chaque instance.

                    -
                    Edité par LilyKianii 11 juin 2019 à 16:47:53

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 juin 2019 à 17:19:43

                      LilyKianii a écrit:

                      DeveCout a écrit:

                      EDIT : Est-ce qu'un élément static m_animationSprite (comme celui-ci sera commun à tous) peu arranger la chose, je ne peux pas essayer de suite donc je demande

                      Non, les membres static sont indépendants des instances de classe.
                      Dans ton cas, tu souhaites justement avoir des valeurs différentes pour chaque instance.

                      -
                      Edité par LilyKianii il y a 25 minutes

                      C'est pas une mauvaise idée par contre d'avoir une seule instance pour tout les objets du même type. Ce que tu peux faire pour arriver à ça, c'est de virer la propriété de Player, et la remplacer par un accesseur virtuel pur. Et chaque sous classe réimplémente la fonction en renvoyant leur variable membre static

                      EDIT :

                      class Player
                      {
                        // ...
                      
                      protected:
                          virtual const AnimationSprite & sprite() = 0;
                      
                        // ...
                      };
                       
                       
                       
                      class Hydrogen : public Player
                      {
                        // ...
                      
                      protected :
                          const AnimationSprite & sprite() final {return m_sprite;}
                      
                      private :
                        static const AnimationSprite m_sprite
                        // ...
                      };
                      
                      //Dans le cpp
                      const AnimationSprite Hydrogen::m_sprite = AnimationSprite(/*blablabla*/)
                       
                       
                       
                      
                      class Nitrogen: public Player
                      {
                        // ...
                      
                      protected :
                          const AnimationSprite & sprite() final {return m_sprite;}
                      
                      private :
                        static const AnimationSprite m_sprite
                        // ...
                      };
                      
                      //Dans le cpp
                      const AnimationSprite Nitrogen::m_sprite = AnimationSprite(/*blablabla*/)




                      -
                      Edité par romantik 12 juin 2019 à 10:57:15

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Dream on, Dream on, Dream until your dream comes true
                        11 juin 2019 à 18:48:45

                        J'aime pô ! >_<

                        Ça fait bizarre de réécrire les mêmes lignes. Mon De La Tourette s'agite...
                        Je considère que le Sprite est celui de Player mais que c'est la classe enfant qui va en changer la valeur.
                        Mais ça fonctionne.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          12 juin 2019 à 10:56:51

                          Ben tout dépend, mais j'ai l'impression que ça n'a pas de sens que Player aie un sprite car le PO ne souhaite pas qu'il lui attribue de valeur
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Dream on, Dream on, Dream until your dream comes true
                            12 juin 2019 à 20:28:40

                            Bon OK : Nouveau problème, j'ai changer de tactique et dorénavant les objets "m_animation..." seront directement dans les classes filles, ce qui donne :

                            #ifndef HYDROGEN_H_INCLUDED
                            #define HYDROGEN_H_INCLUDED
                            #include "Player.h"
                            
                            class Hydrogen : public Player
                            {
                                AnimationSprite m_animationStatic;
                                AnimationSprite m_animationMoving;
                            
                                public:
                                Hydrogen(int posX, int posY);
                                Hydrogen(int posX, int posY, int mass);
                                virtual sf::Sprite getSprite();
                            } ;
                            
                            #endif // HYDROGEN_H_INCLUDED

                            Voilà : plus de code (Mais ça ne le dérange pas plus), mais plus simple
                            ...Mais je n'ai aucune idée de pourquoi mais je n'arrive pas a construire ma classe :

                            Hydrogen::Hydrogen(int posX, int posY):Player(posX,posY),m_animationMoving("Texture/Atom/HydrogenStatic.png",320,256,5,4,2),m_animationStatic("Texture/Atom/HydrogenStatic.png",320,256,5,4,2)
                            {
                            
                            }
                            Hydrogen::Hydrogen(int posX, int posY, int mass):Player(posX,posY,mass),m_animationMoving("Texture/Atom/HydrogenStatic.png",320,256,5,4,2),m_animationStatic("Texture/Atom/HydrogenStatic.png",320,256,5,4,2)
                            {
                            
                            }

                            Mais ils semblerait que les objets sois juste des valeurs aléatoires, comme si un pointeurs pointait au pif quoi, alors si quelqu'un pourrait m'aider parce que la c'est juste ridicule :/




                            • Partager sur Facebook
                            • Partager sur Twitter
                              12 juin 2019 à 23:34:43

                              Alors là, je ne comprend rien à ce que tu racontes :/

                              Qu'est-ce que tu veux dire par "je n'arrive pas a construire ma classe" ?

                              Et qu'est-ce qui te fais dire "ils semblerait que les objets sois juste des valeurs aléatoires" ?

                              • Partager sur Facebook
                              • Partager sur Twitter
                              Dream on, Dream on, Dream until your dream comes true
                                13 juin 2019 à 7:16:39

                                Surtout les objets d'une classe qu'on n'est pas arrivé à construire.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  13 juin 2019 à 15:00:03

                                  J'entend que mon objet m_animationStatic/m_animationMoving ne se créer pas correctement ! Dans le sens où par exmemple : si je lui donne une valeurs m_x=100, alors si je lui demande cette valeurs gracee à un getteur il ne me donnera pas 100...Mais plutot quelque chose du genre 10048372, Ce qui est assez genant!
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    13 juin 2019 à 15:24:36

                                    Ok

                                    Ben c'est pas dans ce que tu nous as envoyé, on peut pas t'aider sans le code, pour repérer où est ton erreur dans l'implémentation

                                    ( /!\ tu nous parles de m_x mais dans le code que tu nous as envoyé je ne vois que m_posX, est-ce juste un abus de langage ? )

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Dream on, Dream on, Dream until your dream comes true
                                      13 juin 2019 à 18:39:47

                                      Désolé c'était juste à titre d'exemple, j'ai eu un peu de mal à m'exprimer et a retirer la partis du code qui était superflu, le code fonctionne (je ne sait pas vraiment pourquoi d'ailleurs ^^'). Pour clôturer le post et avoir une réponse voilà le code final que j'ai obtenue :

                                      Player.h/Player.cpp reste intact, tout est dans les classes filles :

                                      Hydrogen.h

                                      #ifndef HYDROGEN_H_INCLUDED
                                      #define HYDROGEN_H_INCLUDED
                                      #include "Player.h"
                                      
                                      class Hydrogen : public Player
                                      {
                                          AnimationSprite m_animationStatic;
                                          AnimationSprite m_animationMoving;
                                      
                                          public:
                                          Hydrogen(int posX, int posY);
                                          Hydrogen(int posX, int posY, int mass);
                                      } ;
                                      
                                      #endif // HYDROGEN_H_INCLUDED
                                      

                                      Hydrogen.cpp

                                      #include <iostream>
                                      #include <SFML/System.hpp>
                                      #include <SFML/Graphics.hpp>
                                      #include "Player.h"
                                      #include "Hydrogen.h"
                                      #include "AnimationSprite.h"
                                      
                                      Hydrogen::Hydrogen(int posX, int posY):Player(posX,posY),m_animationMoving("Texture/Atom/HydrogenStatic.png",320,256,5,4,2),m_animationStatic("Texture/Atom/HydrogenStatic.png",320,256,5,4,2)
                                      {
                                      
                                      }
                                      Hydrogen::Hydrogen(int posX, int posY, int mass):Player(posX,posY,mass),m_animationMoving("Texture/Atom/HydrogenStatic.png",320,256,5,4,2),m_animationStatic("Texture/Atom/HydrogenStatic.png",320,256,5,4,2)
                                      {
                                      
                                      }
                                      

                                      /!\ : Les objets m_animationMoving et m_animationStatic sont les mêmes dans les constructeur car je n'ai pas encore fait les autres Textures, voilà voilà ^^


                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        14 juin 2019 à 8:31:14

                                        Il fonctionne parce que tu as ajouté des corrections et enlevé des erreurs.

                                        Et tu comprendrais si tu comparais les versions, mais bien sûr tu as probablement balancé ce qui ne marchait pas. C'est un tort parce qu'on apprend beaucoup en etudiant les erreurs, vu qu'on les refait souvent.

                                        -
                                        Edité par michelbillaud 14 juin 2019 à 8:33:36

                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Attribut de classe : Initialisation

                                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                        • Editeur
                                        • Markdown