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 :

Comment vérifier qu'un objet d'une classe est créé ?


Sujet :

C++

  1. #1
    Membre émérite
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Novembre 2011
    Messages
    1 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Novembre 2011
    Messages : 1 503
    Points : 2 657
    Points
    2 657
    Par défaut Comment vérifier qu'un objet d'une classe est créé ?
    Bonjour à tous !

    Mon problème est très simple mais après avoir fouiné un peu partout, je n'ai pas trouvé de réponse précise...

    J'ai deux classes, l'une faisant référence à l'autre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class player
    {
          public:
                  int id;
                  std::string name;
                  bool GM;
                  bool mayor;
     
                  card player_card; //<- mon autre classe
     
         public:
                  virtual void info();
                  //méthodes en tout genre
    }
    J'aimerai, dans ma méthode "info()", savoir si une classe "card" à bien été attribuée à "player" ou pas.

    Ma méthode "info()" :
    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
    void player::info()
    {
         display();
         if (GM == true)
         {...}
         else
         {...            
                if (mayor == true)
                {...}
                else
                {...}
         }
         cout << endl;
     
         // ICI J'aimerai placer la condition, à savoir "Est-ce que player_card existe pour ce player ?"
         {
                cout << name << " has " << player_card.vote << " vote and " << player_card.additional_vote << " additional vote." << endl;
         }
    }
    Voila, c'est simple mais je ne sais pas... Je ne suis pas très fort en C++... J'avais pensé à créer un "flag" dans ma classe "player" mais cela m'oblige à changer tout mon programme. Peut-être y a-t-il plus simple.

    Merci beaucoup par avance pour le temps que vous me consacrerez !


    Kimy from Ireland.
    La logique :
    • Plus ya de gruyère, moins ya de gruyère.
    • Plus tu pédales moins vite, moins tu avances plus vite.
    Plusoyer les réponses pertinentes et n'oublier pas de résolver en fin de post !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut:

    La réponse simple :
    Tous les membres d'une classe sont d'office créés (en faisant appel à leur constructeur par défaut si l'on ne définit pas de constructeur personnel) lorsque l'on crée une instance de cette classe.

    C'est à dire que, lorsque tu te trouvera avec un code proche de Player myPlayer;, il y aura d'office un objet de type Card qui sera créé pour prendre la place de player_card.

    les considérations exterieures
    Maintenant, si la question est
    mon joueur peut ne pas avoir de carte, comment faire pour savoir s'il en a une ou non
    la réponse est
    il faut passer par un pointeur, auquel on prendra soit d'affecter la valeur NULL (null_ptr en C++11) quand le joueur n'a effectivement pas de carte.
    mais l'utilisation du pointeur impliquera qu'il faudra se poser d'autres questions, telles que:
    • qui est réellement responsable de la création de la carte
    • qui est réellement responsable du maintient de la carte
    • qui est réellement responsable de la destruction de la carte
    • la carte est-elle intervient-elle dans une hiérarchie d'héritage public
    Enfin, si la question est de savoir si la carte est une carte "valdie" (le roi de carreaux par opposition à une carte sans valeur correcte qui a été "créée parce qu'on en a besoin"), ce n'est pas du ressort du joueur, mais de la carte.

    Ce serait alors la carte qui doit pouvoir dire "je suis valide" ou, à l'inverse "je suis invalide", et le joueur pourra à tout moment interroger la carte sur "es tu valide "
    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 émérite
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Novembre 2011
    Messages
    1 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Novembre 2011
    Messages : 1 503
    Points : 2 657
    Points
    2 657
    Par défaut

    Waoh ! Si j'avais su que cela poserai tant de soucis...

    Ma question est assez simple : ce programme me permetterait-il de répondre à mon problème ?
    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
    void player::info()
    {
         display();
         if (GM == true)
         {...}
         cout << endl;
     
         if (&player_card == NULL)
         {
                 cout << name << " has no card.";
         }
         else
         {
                 cout << name << " has " << player_card.vote << " vote and " << player_card.additional_vote << " additional vote." << endl;
         }
         cout << endl;
    }
    Il semblerait que non... Je n'ai probablement pas tout compris...

    Merci beaucoup en tout cas ! =D
    La logique :
    • Plus ya de gruyère, moins ya de gruyère.
    • Plus tu pédales moins vite, moins tu avances plus vite.
    Plusoyer les réponses pertinentes et n'oublier pas de résolver en fin de post !

  4. #4
    Membre émérite
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Novembre 2011
    Messages
    1 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Novembre 2011
    Messages : 1 503
    Points : 2 657
    Points
    2 657
    Par défaut
    Après réflexion, il faut que j'impose, dans ma classe "player" que le pointeur de player_card aille sur "NULL", c'est bien cela ?

    Là, j'obtiens une addresse "card" à chaque création de "player"...

    Comment puis-je imposer ce pointeur d'aller sur NULL ? =S
    La logique :
    • Plus ya de gruyère, moins ya de gruyère.
    • Plus tu pédales moins vite, moins tu avances plus vite.
    Plusoyer les réponses pertinentes et n'oublier pas de résolver en fin de post !

  5. #5
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Bonjour.

    Citation Envoyé par Kimy_Ire Voir le message
    Là, j'obtiens une addresse "card" à chaque création de "player"...
    C'est normal.
    Comme vient de te le dire koala01, l'objet player::player_card est forcément créé quand tu crées une instance de player.

    Citation Envoyé par Kimy_Ire Voir le message
    Comment puis-je imposer ce pointeur d'aller sur NULL ? =S
    Avant de répondre à cette question, j'en ai deux pour toi.
    1. Sais-tu ce qu'est un pointeur ? une référence ?
    2. Si oui, sais-tu comment les utiliser ?

  6. #6
    Membre émérite
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Novembre 2011
    Messages
    1 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Novembre 2011
    Messages : 1 503
    Points : 2 657
    Points
    2 657
    Par défaut
    Je ne suis pas un expert mais je dirais :

    Un pointeur "point vers" une adresse. On défini son type : int *x.
    Le type de référence de x est "int".

    Ensuite pour obtenir l'adresse d'une variable on utilise l'opératuer "&".

    x = &y.

    Au final x à en mémoire une adresse : FFAB:1337 et sa valeur est "*x".

    Voila... Je dirais quelque chose comme ça...
    La logique :
    • Plus ya de gruyère, moins ya de gruyère.
    • Plus tu pédales moins vite, moins tu avances plus vite.
    Plusoyer les réponses pertinentes et n'oublier pas de résolver en fin de post !

  7. #7
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Hum...
    Tu as l'intuition, c'est déjà ça...
    Mais ce n'est pas avec ça que tu vas les utiliser correctement.

    F.A.Q. C: Les pointeurs
    F.A.Q. C++: Les références

  8. #8
    Membre émérite
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Novembre 2011
    Messages
    1 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Novembre 2011
    Messages : 1 503
    Points : 2 657
    Points
    2 657
    Par défaut
    Boah... Je laisse tomber...

    J'ai eu beau lire les questions qui me semblaient importantes pour mon problème, je ne m'en sort pas...

    J'ai fait un dernier test en tentant d'assigner "&player_card = NULL;" à toutes les méthodes de "player" mais j'ai un message d'erreur du type
    non-lvalue in assignment
    Je vais faire un truc sale avec mes "flags" mais je ne vois pas d'autre solution... enfin... je pense que je n'aurais pas le temps ! xD

    Merci d'avoir tenté de m'aider et d'avoir pris du temps pour moi !


    Kimy from Ireland
    La logique :
    • Plus ya de gruyère, moins ya de gruyère.
    • Plus tu pédales moins vite, moins tu avances plus vite.
    Plusoyer les réponses pertinentes et n'oublier pas de résolver en fin de post !

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Kimy_Ire Voir le message

    Waoh ! Si j'avais su que cela poserai tant de soucis...
    Ce n'est pas que ca pose des soucis, c'est que tu ne pose visiblement pas la bonne question.

    Comme je te l'ai dit, le principe est simple : comme ta classe Player dispose d'un membre de type card, chaque fois que tu créeras un objet de type Player, il y aura d'office un objet de type card qui sera créé (si, du moins, la classe card est "défaut constructible" (susceptible d'être construite sans donner de paramètre), c'est garanti!
    Ma question est assez simple : ce programme me permetterait-il de répondre à mon problème ?
    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
    void player::info()
    {
         display();
         if (GM == true)
         {...}
         cout << endl;
     
         if (&player_card == NULL)
         {
                 cout << name << " has no card.";
         }
         else
         {
                 cout << name << " has " << player_card.vote << " vote and " << player_card.additional_vote << " additional vote." << endl;
         }
         cout << endl;
    }
    Il semblerait que non... Je n'ai probablement pas tout compris...
    Le problème à voir ton code, c'est que tu ne poses visiblement pas la bonne question...

    Il ne faut donc pas t'étonner de ne pas recevoir la bonne réponse
    La bonne quesiton serait en effet plutôt du genre de
    Comment puis-je m'assurer du fait qu'un joueur dispose d'une carte
    voir
    Comment puis-je m'assurer du fait qu'un joueur dispose d'une carte valide
    Et, comme j'ai l'habitude de décoder les mauvaises questions, j'ai tout de suite pris un peu d'avance avec mes "si la question est"

    Mais le fait est que, bien qu'elles ne diffèrent que par un mot, ces deux questions impliquent réellement deux point de vue différents, qui peuvent avoir de sérieuses répercussions sur l'ensemble du programme.

    En effet, la première question va partir du principe que toute carte est d'office valide.

    La seule possibilité pour représenter l'absence de carte (vu que, si carte il y a, elle est valide ) est... d'utiliser un pointeur que l'on veille à mettre à NULL s'il n'y a pas de carte.
    Ta classe Player devrait donc être modifiée pour 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
    class player
    {
          public:
                  int id;
                  std::string name;
                  bool GM;
                  bool mayor;
     
                  card * player_card; //<- mon autre classe
     
         public:
                  virtual void info();
                  //méthodes en tout genre
    }
    avec une fonction info() 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
    void Player::info()
    {
        /* tout ce qui peut etre fait avant d'avoir vérifié si le joueur a
         * une carte
         */
        if( player_card == NULL)
        {
            std::cout<<"le joueur n'as pas de carte"<<std::endl;
        } 
        else
        {
            /* tout ce qui dépend du fait que le joueur a une carte */
        }
        /* tout ce qui doit etre fait après vérification, mais qui ne dépend
         * pas du fait que le joueur ait ou non une carte
         */ 
    }
    Mais, dés qu'il est question de pointeurs, tu dois avoir un véritable festival de grosses lumière rouge qui s'illuminent dans la tête, car:
    1. la mauvaise gestion des pointeurs est sans doute la cause principale de bug, depuis que la notion "d'adresse à laquelle se trouve une donnée" a été mise au point
    2. Qui dit pointeur peut dire gestion dynamique de la mémoire et donc risque de fuite mémoire ou de tentative de double libération de la mémoire (les deux pouvant rapidement mener à des catastrophes)
    3. Qui dit "objet pointé" par un pointeur dit qu'il faut s'assurer que la durée de vie de l'objet pointé est, au minimum égale à toute la période pendant laquelle le pointeur pointe effectivement sur l'objet en question.
    4. qui dit (3) dit qu'il faut donc avoir une bonne connaissance de qui s'occupe de la construction, du maintient en mémoire et de la destruction des objets pointés
    5. Le (4) nous fais nous rendre compte que nous n'avons pas, au niveau du forum, une connaissance suffisante de l'ensemble du projet pour garantir l'absence de risque ni pour fournir une solution prenant le (3) en compte sans risquer de "tout casser" dans le projet

    La deuxième question impliquerait par contre que l'on considère comme possible le fait qu'une carte soit considérée comme invalide.

    La première question qu'il faudrait alors se poser serait alors proche de
    Qu'est ce qui permet à une carte d'être invalide
    et, sur base de la réponse obtenue à cette question, nous pourrions considérer que toute carte créée par défaut (comme ce pourrait etre le cas de celle détenue par le joueur) serait considérée comme invalide, et de prévoir, en parallèle, un constructeur acceptant les paramètres permettant de... construire une carte qui sera considérée comme valide.

    A ce moment là, ce serait la carte qui pourrait répondre à la question "es tu valide " en fonction des valeurs qu'elle manipule en interne.

    Le service qui consiste à répondre à cette question serait, tout simplement, fourni par une fonction membre isValid() qui implémenterait une logique permettant de déterminer en fonction des valeurs qu'elle manipule en interne si, oui ou non, la carte est valide.

    Tu pourrais alors laisser ta classe Player inchangée (mais bon, tu auras modifié ta classe card ) et la fonction info() ressemblerait alors à 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
    void Player::info()
    {
        /* tout ce qui peut etre fait avant d'avoir vérifié si le joueur a
         * une carte
         */
        if( player_card.isValid())
        {
            std::cout<<"le joueur n'as pas de carte"<<std::endl;
        } 
        else
        {
            /* tout ce qui dépend du fait que le joueur a une carte */
        }
        /* tout ce qui doit etre fait après vérification, mais qui ne dépend
         * pas du fait que le joueur ait ou non une carte
         */ 
    }
    On évite les problèmes liés aux pointeurs, mais, d'un autre coté, on rajoute peut etre une responsabilité à la carte qu'elle n'a peut etre pas lieu d'avoir

    Mais, encore une fois, nous n'avons pas la connaissance suffisante du projet au niveau du forum pour dire s'il est (ou non) intéressant de permettre "à n'importe quoi" de demander à une carte si elle est valide ou non
    Citation Envoyé par Kimy_Ire Voir le message
    Après réflexion, il faut que j'impose, dans ma classe "player" que le pointeur de player_card aille sur "NULL", c'est bien cela ?

    Là, j'obtiens une addresse "card" à chaque création de "player"...

    Comment puis-je imposer ce pointeur d'aller sur NULL ? =S
    La réponse à cette question est relativement simple et porte un nom magique "constructeur".

    Un constructeur est une fonction particulière de la classe qui sera d'office appelée dés qu'une instance de la classe est créée, que la création se fasse en ayant recours à l'allocation dynamique de la mémoire ou non (cf la page de la FAQ qui en parle)

    L'idée est de se dire que, si l'on ne donne pas un pointeur vers un objet de type card, le joueur n'as pas de carte, et qu'il faut donc initialiser le pointeur à NULL

    Si, par contre, on fournit un pointeur vers un objet existant de type card, nous initialiserons le pointeur membre du joueur avec... l'adresse à laquelle se trouve la carte en question
    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

  10. #10
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Kimy_Ire Voir le message
    Boah... Je laisse tomber...

    J'ai eu beau lire les questions qui me semblaient importantes pour mon problème, je ne m'en sort pas...

    J'ai fait un dernier test en tentant d'assigner "&player_card = NULL;" à toutes les méthodes de "player" mais j'ai un message d'erreur du type


    Je vais faire un truc sale avec mes "flags" mais je ne vois pas d'autre solution... enfin... je pense que je n'aurais pas le temps ! xD

    Merci d'avoir tenté de m'aider et d'avoir pris du temps pour moi !


    Kimy from Ireland
    De toute évidence, il te manque quelques notions importantes en C++:

    Un pointeur se déclare sous la forme de Type * nom_du_pointeur; et prend comme valeur l'adresse à laquelle se trouve la variable de du type indiqué.

    Pour travailler avec les pointeurs, il faut donc utiliser la version de Player que j'ai présenté dans mon intervention précédente lorsque je répondais à la question "comment puis-je m'assurer qu'un joueur a une carte".

    Une fois le pointeur déclaré, il est possible de lui donner une adresse sous différentes forme
    • nom_du_pointeur = NULL; qui lui donne la seule adresse garantie invalide (et qui permet dans notre cas de dire que le joueur ne dispose pas d'une carte
    • nom_du_pointeur = autre_pointeur_de_meme_type; qui fait que nom_du_pointeur et autre_pointeur_de_meme_type pointent tous les deux vers le même objet
    • nom_du_pointeur = &objet_existant; qui fait que nom_du_pointeur pointe ver l'objet existant indiqué
    • nom_du_pointeur = new Type; qui va créer dynamiquement on nouvel objet de type Type et qui va faire en sorte que nom_du_pointeur pointe vers cet objet (il ne faudra pas oublier de libérer la mémoire allouée à cet objet au plus tard avant de perdre le dernier pointeur pointant dessus, sous peine d'avoir une fuite mémoire )
    Mais, effectivement, il me semblerait peut etre bon que tu lise un bouquin ou que tu suive n'importe quel tutorial dédié aux débutants en C++ avant de commencer à essayer des choses "au petit bonheur la chance"
    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 émérite
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Novembre 2011
    Messages
    1 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Novembre 2011
    Messages : 1 503
    Points : 2 657
    Points
    2 657
    Par défaut
    Merci pour tout en tout cas ! J'ai lu avec attention tout ce que vous avez écris et j'essaye de m'en sortir avec les moyens du bord !

    Merci encore !

    Kimy from Ireland.
    La logique :
    • Plus ya de gruyère, moins ya de gruyère.
    • Plus tu pédales moins vite, moins tu avances plus vite.
    Plusoyer les réponses pertinentes et n'oublier pas de résolver en fin de post !

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

Discussions similaires

  1. [FAQ] [jQuery] Comment puis-je vérifier si un élément a une classe en particulier ?
    Par SylvainPV dans le forum Contributions JavaScript / AJAX
    Réponses: 12
    Dernier message: 19/03/2014, 21h42
  2. Réponses: 8
    Dernier message: 26/03/2011, 20h40
  3. Réponses: 8
    Dernier message: 16/02/2007, 15h55
  4. Réponses: 12
    Dernier message: 03/11/2005, 18h45
  5. [Juridique] Comment réutiliser le code source d'une classe ?
    Par mathieu dans le forum Général Java
    Réponses: 8
    Dernier message: 17/05/2004, 13h40

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