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 :

[PROBLEME] Déclaration pointeur static sur Class Modele


Sujet :

Langage C++

  1. #1
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Par défaut [PROBLEME] Déclaration pointeur static sur Class Modele
    Bonjour,

    Je souhaite créer une classe modèle. A l'école on m'a appris cette méthode. On déclarer un pointeur static dans la classe et on crée une fonction static Mdl() qui renvoie ce pointeur. Cela permet de n'avoir qu'à instancier une seule fois la classe pour pouvoir l'utiliser dans tout le code. Très pratique !
    Mais voilà le problème, j'ai fait ces solutions sur Java et C# et en C++ je suis confronté à un petit problème.

    Voilà ma classe.hpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Controler
    {
    	private:
    	static Controler* mdl;
     
    ...
     
    	static Controler* Mdl(void);
     
    };
    Et une partie du .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
     
    #include "Controler.hpp"
     
    using namespace std;
    using namespace sf;
     
    //Controler::mdl = NULL;
     
    Controler::Controler()
    {
    	mdl = this;
    }
     
    Controler* Controler::Mdl()
    {
    	return mdl;
    }
    Voilà le problème. J'ai appris qu'une variable static devait toujours être obligatoirement initialisée sinon le linker hurle.

    Si je commente Controler::mdl = NULL; le linker hurle effectivement ceci :

    Erreur 2 fatal error LNK1120: 1 externes non résolus C:\Users\Tbop\Documents\Visual Studio 2008\Projects\GameEngine\Debug\GameEngine.exe
    Erreur 1 error LNK2001: symbole externe non résolu "private: static class Controler * Controler::mdl" (?mdl@Controler@@0PAV1@A) Controler.obj
    Si au contraire je décommente il me hurle ceci :

    Erreur 1 error C4430: spécificateur de type manquant - int est pris en compte par défaut. Remarque*: C++ ne prend pas en charge int par défaut c:\users\tbop\documents\visual studio 2008\projects\gameengine\gameengine\controler.cpp 6
    Erreur 2 error C2040: 'mdl'*: les niveaux d'indirection de 'int' et de 'Controler *' sont différents c:\users\tbop\documents\visual studio 2008\projects\gameengine\gameengine\controler.cpp 6
    Je tourne en rond et je ne sais vraiment plus quoi faire !

    Merci de votre aide

  2. #2
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Par défaut
    C'est bon j'ai trouvé le problème.

    La solution est qu'il faut redéfinir le type de la variable static quand on l'initialise à l'extérieur :

    Controler* Controler::mdl = NULL;

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Il faut effectivement rappeler le type de la variable.
    Cependant, on dit souvent des bêtises à l'école et je suis dubitatif face à cette approche avec des variables statiques.
    En gros, tu as fait plus ou moins un singleton, et voici une bonne critique de cette approche : Etes-vous atteint de Singletonite ?

  4. #4
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Par défaut
    Oui c'est ça, du coup j'ai appris le mot en même temps que la solution hier sur internet. C'est une sorte de singleton en effet. Sauf qu'il n'est pas encore sécurisé avec des constructeurs privés... Ce que je m'apprête à faire pour avoir un code toujours plus propre.

    Je vais par ailleurs lire de ce pas ton article !

    Merci !

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Dis autrement, avoir des singletons pour retrouver le modèle depuis le contrôleur est absurde. Comment vas-tu faire si tu as plusieurs documents avec chacun leur contrôleur ?
    Autre question : pourquoi ton contrôleur doit-il retourner le modèle ?

  6. #6
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Par défaut
    Il ne retourne pas le modèle. Il retourne juste son pointeur. J'ai la facheuse habitude d'appeler ça Mdl à chaque fois mais ce n'est pas le cas.

    En fait je suis actuellement en train de repenser une architecture plus intelligente à l'heure actuelle.

  7. #7
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Par défaut
    En fait je voudrais juste forcer une classe à n'avoir qu'une seule instance sans pour autant qu'elle soit accessible de partout.

    Ce qui enlève une grosse partie de la définition d'un singleton.

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Je ne vois pas pourquoi Modele, Vue ou Controleur ne serait instanciable qu'une seule fois . Je répète, comment feras-tu si tu veux gérer plusieurs documents ?

  9. #9
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Par défaut
    En fait je ne sais plus si je l'ai précisé mais j'essaye de faire un moteur de jeu générique.

    Dans ce moteur la boucle de jeu se décomposera grossièrement comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    while(isRunning)
    {
    //Capture les Event et appelle des fonctions du modele
    Controler::Mdl()->CheckEvent();
     
    //Dessine la mise à jour du modele
    Draw();
    }
    En fait à chaque changement d'interface (titre, cutscene, menu, jeu), le Controler aura des templates d'événements déjà configurés du type Controler::Mdl()->LoadEventsMenu(). Donc voilà j'évite ainsi de faire un controleur par document. Est-ce que cela répond à ta question ?


    PS : Hier sans faire exprès j'ai fait une manip au clavier qui malgré le redémarrage semble persister. En fait la commande alt ne semble plus fonctionner, ainsi par exemple pour faire les accolades je suis obligé de faire Ctrl+Alt+4 et non Alt+4 tout court. Est-ce que quelqu'un sait comment revenir en mode normal ?

  10. #10
    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,

    Je voudrais juste rebondir sur
    Citation Envoyé par thebop Voir le message
    Il ne retourne pas le modèle. Il retourne juste son pointeur. <snip>
    parce que j'ai l'impression que tu n'a pas compris une chose importante.

    Un pointeur, ce n'est une variable de type numérique un peu particulière dans le sens où elle représente... l'adresse mémoire à laquelle on trouvera un objet du type indiqué.

    Si tu renvoie un pointeur, tu dois avoir la certitude que l'adresse mémoire contient bel et bien un objet du type indiqué, autrement tu te prépare à des problèmes sans noms

    Sans mauvais jeu de mots, un pointeur "fait donc référence" (au sens commun du terme) à un objet, tout comme une référence (au sens C++ du terme) fait référence (au sens commun du terme à nouveau) à un objet (avec cependant certaines certitudes supplémentaires).

    La seule différence qu'il y ait entre le fait de renvoyer un pointeur (ou une référence) sur un objet et le fait de renvoyer cet objet lui-même, c'est que tu évites éventuellement la copie de l'objet (cela peut dépendre de la manière dont tu récupère la référence ou le pointeur ).

    Pour le reste, il n'y a strictement aucune différence entre renvoyer quelque chose qui "fait référence à un objet" et renvoyer... l'objet lui-même

    Dés lors, bien que tu renvoye "un pointeur sur ton modèle", cela revient strictement au même (en dehors du fait que tu évites la copie) que si tu renvoyais... ton modèle

    Enfin, je voudrais rebondir également sur
    En fait je voudrais juste forcer une classe à n'avoir qu'une seule instance sans pour autant qu'elle soit accessible de partout.

    Ce qui enlève une grosse partie de la définition d'un singleton.
    La meilleure manière de t'assurer qu'une classe n'existera que sous la forme d'une instance unique est encore... de veiller à ce qu'il n'y ait qu'un objet qui crée cette instance.

    Ainsi, dans le cadre de ton jeu video, ton gestionnaire d'événement ne doit exister qu'au travers... de la partie de jeu video, qui ne doit elle-même exister que... durant la durée de la fonction main.

    Ainsi, si tu as "simplement" ta classe EventControler qui s'occupe de gérer les évènements, tu peux avoir une classe Game qui prend la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Game
    {
        public:
            /* tout ce qui est intéressant */
            int run(); // la boucle principale de jeu
                       // renvoie 0 si le jeu a été quitté correctement
                       //         autre chose s'il "a planté"
        private:
            EventControler evt_; // un seul et unique contrôleur d'évènements
                                 // dans la partie
    };
    et la fonction principale (main) peut donc être, tout simplement,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
        /* on crée une instance unique de Game
         * ce qui nous assure qu'il n'y a qu'une instance unique de EventControler
         */
        Game g; 
        int final=g.run();
        /* quand on arrive ici, on a mis fin à la partie */
        return 0;
    }
    Après, tu me demandera sans doute comment faire pour disposer du pointeur sur le gestionnaire d'évènements depuis les classes qui doivent y accéder...

    La réponse est finalement bien simple: tu "rajoute" un membre EventControler * evt_ dans les classes qui doivent y accéder et... tu transmet l'adresse du membre evt_ de game au constructeur de ton objet de manière à pourvoir initialiser le pointeur
    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

  11. #11
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Par défaut
    Pour la première partie de ta longue et très constructive réponse koala01 :

    En fait ma phrase était très mal formulée. Je voulais dire que Mdl ne renvoyait pas un pointeur static vers une prétendue autre classe de type Model mais bien vers le pointeur static de la classe Controler. Donc merci pour les explications mais... ça fait longtemps que je sais ce qu'est un pointeur !


    Pour la deuxième partie de la réponse : c'est pas bête ! (et moins compliqué en plus qui plus est !)

  12. #12
    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
    A vrai dire, je fais partie de ceux qui estiment que le fait d'exprimer clairement un problème permet déjà d'y apporter plus de cinquante % de la réponse, et que, par conséquent, le fait d'exprimer clairement est primordial (ce qui ne m'empêche absolument pas de parfois m'exprimer extrêmement mal )

    Quand je t'aurai dit que certaines réponses à la question "Qu'est-ce qu'un pointeur?" sont parfois... disons simplement folkloriques (), tu comprendra que je ne voulais pas te heurter, mais que j'ai préférer partir du principe qu'une explication claire sur le sujet était nécessaire...

    Si pas pour toi, pour les autres qui liront cette discussion

    Si je t'ai vexé d'une quelconque manière de ce point de vue, je te présente mes excuses les plus plates

    Pour le reste, je n'ai fait qu'appliquer les conseils que je donne dans ma signature
    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

  13. #13
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Par défaut
    Oh non ne t'inquiète pas koala tu m'as tout sauf vexé ! Je viens effectivement ici pour apprendre donc cela aurait été une réaction bien stupide de ma part.

    Je disais juste que bien que ton message était plus que clair et pédagogique tu n'aurais pas dû t'embêter à me ré-expliquer ce qu'était un pointeur (la base de la base !)

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

Discussions similaires

  1. petit probleme de pointeur dans strcat sur le projet de mes etudiant
    Par hamhama-group dans le forum Bibliothèque standard
    Réponses: 8
    Dernier message: 04/12/2007, 18h34
  2. Réponses: 4
    Dernier message: 15/10/2006, 18h05
  3. Problème de pointeurs sur classe
    Par fabiin dans le forum Delphi
    Réponses: 1
    Dernier message: 05/08/2006, 18h13
  4. pointeur membre static de classe
    Par Ca$ul dans le forum C++
    Réponses: 3
    Dernier message: 26/08/2004, 13h02
  5. Probleme de pointeur sur une fonction
    Par nicky78 dans le forum C
    Réponses: 2
    Dernier message: 23/05/2004, 20h26

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