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 :

Pourquoi mon set ne se rempli pas


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Novembre 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 14
    Par défaut Pourquoi mon set ne se rempli pas
    bonjour,

    j'ai un probleme pour l'insertion d'objets dans un set...

    alors voila à peu près mon 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
     
    class A {
       public : 
          void insert(string s){
             set.insert(s); 
             //ici, s est bien dans set
          }
       private : 
          set<std::string> set;
    }
     
    class B {
       public :
          void createObject(string key, string s){
             map.find(key).insert(s);
             //mais ici il n'y est plus ...
          }
          void insert(string s, A a){
             map.insert(make_pair(s,a));
          }
       private :
          map<string, A> map;
    }
     
    main(){
       B b;
       A a;
       b.createObject("toto",a );
    }
    Alors voila le souci: lors de la création d'objet, j'insert dans le set de A un string lorsque l'on ets dans A::insert, le string ets bien inséré mais dès que l'on qui la méthode, le string n'y ets plus ...

    Si vous avez besoin de plus d'explications demander, j'essaierai de reformuler mon problème.

    Si quelqu'un pouvait m'expliquer ce phénomène et aussi comment y remédier, ce serai cool

    Merci d'avance pour l'aide apportée

  2. #2
    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, et bienvenue sur le forum

    Avant tout, je souhaiterais te donner quelques conseils d'ordre général:

    D'abord, lorsqu'il s'agit de fournir un argument à une fonction, de penser à le passer par référence (constante ou non) dés qu'il ne s'agit pas d'un type primitif.

    En effet, lorsque tu passe un argument par valeur (ex: void foo(string s) ), il y a copie de l'objet transmis.

    Cette copie risque de prendre énormément de ressources (en terme de mémoire et de temps) et peut même poser un certain nombre de problèmes car certaines classes ne sont pas destinées à être copiées.

    La référence va agir comme un alias de l'objet à transmis et permettra donc d'en éviter la copie.

    Par contre, comme il s'agit d'un alias de l'objet transmis, les modifications apportées à l'objet dans la fonction appelée seront répercutées dans la fonction appelante.

    C'est la raison pour laquelle, si l'objet transmis n'est pas destiné à être modifié dans la fonction appelée, il est conseillé de le transmettre par référence constante.

    L'avantage d'agir ainsi sera en plus de permettre de créer une variable temporaire non nommée, et donc de permettre un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* soit la fonction */
    void foo(string const & s)
    {
        ...
    }
    int main()
    {
        foo("Salut toi"); /* il existe un constructeur de string prenant une
                           * chaine de caractères "C style"
                           */
        return 0;
    }
    En outre, je présumes (peut être à tord) que les types map, set et string que tu manipule sont ceux fournis par le standard et que tu as placé une directive using namespace std; quelque part...

    Cette directive ne devrait jamais se trouver dans un fichier d'en-tête ( *.h ou *.hpp) car elle a la sale manie de se propager dans tous les fichiers dans lesquels le fichier d'en-tête est inclus, que ce soit de manière directe ou indirecte (elle sera appliquée dans le fichier qui inclus le fichier qui inclus le fichier qui... le fichier dans lequel la directive se trouve)

    Mais, quoi qu'il en soit, il est souvent dangereux de créer une variable dont le nom est... celui qui correspond au nom du type manipulé...

    Il serait donc des plus intéressants de trouver un nom plus opportun pour représenter les membres A::set et B::map...

    Enfin, la réponse est finalement toute simple: ton code est tout bonnement incomplet et faux

    En effet, la fonction membre de la classe map find va renvoyer un itérateur sur l'objet correpondant à la clé recherchée... s'il existe.

    S'il n'existe pas, tu obtiendra un itérateur pointant sur... ce qui suit le dernier élément de la map et donc, tout à fait invalide.

    De plus, il faut savoir que:
    • Les itérateurs ont une sémantique de pointeurs (pour accéder aux données qu'ils représentent, il faut soit prendre "ce qui est pointé par" l'itérateur, soit utiliser la flèche "->" pour accéder à la donnée)
    • Les itérateurs de la classe map représente un couple (une std::pair) cle / valeur (la cle étant accessible sous le nom de first et la valeur étant accessible par second).


    Pour que ton code fonctionne, il faut donc:
    1. vérifier que l'itérateur renvoyé par map.find() n'est pas équivalent à map.end()
    2. si c'est le cas, il faut
      1. rajouter un nouvel objet dans map
      2. récupérer ce nouvel objet par find

    une fois ceci fait, il faut donc veiller à accéder à la fonction insert() de ce qui est représenté par la valeur second de l'itérateur sur la map obtenu.

    Le code serait donc 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
    class B {
       public :
          void createObject(string key, string s){
             map<string,A>::iterator it= map.find(key);
             if(it = map.end())
             {
                 insert(key,A());
                 it=map.find(key);
             }
             (*it).second.insert(s);
          }
          void insert(string s, A a){
             map.insert(make_pair(s,a));
          }
       private :
          map<string, A> map;
    }
    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 Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Pour que ton code fonctionne, il faut donc:
    1. vérifier que l'itérateur renvoyé par map.find() n'est pas équivalent à map.end()
    2. si c'est le cas, il faut
      1. rajouter un nouvel objet dans map
      2. récupérer ce nouvel objet par find

    une fois ceci fait, il faut donc veiller à accéder à la fonction insert() de ce qui est représenté par la valeur second de l'itérateur sur la map obtenu.
    C'est tout à fait exact, mais pourquoi ne pas lui dire que l'opérateur [] fait justement tout ça sans qu'on ait à s'en préoccuper

  4. #4
    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
    Citation Envoyé par white_tentacle Voir le message
    C'est tout à fait exact, mais pourquoi ne pas lui dire que l'opérateur [] fait justement tout ça sans qu'on ait à s'en préoccuper
    Bonne question ... Peut être simplement parce que je n'y ait pas pensé

    Je dois avouer que c'est un comportement qui m'oripile à ce point de l'opérateur [] que je ne l'utilise quasiment jamais...

    Et voilà justement le cas où son utilisation s'avère intéressante
    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

  5. #5
    Membre averti
    Inscrit en
    Novembre 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 14
    Par défaut
    Bonjour,

    Merci pour votre aide, effectivement, je modifiais des copies ...

    Mais en tout cas t'inquiète pas koala01, j'ai bien un .cpp et un .hpp avec un using namespace std; juste dans le .cpp

    J'ai bien tout corrigé et j'utilise des pointeurs partout

    Merci encore pour votre aide, ça marche impeccablement !!

    A plous sur ce forum !

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

Discussions similaires

  1. Pourquoi mon animation Flash ne marche pas sur IE ?
    Par Audrey75 dans le forum Flash
    Réponses: 23
    Dernier message: 23/12/2008, 13h58
  2. Pourquoi mon XmlInclude( dataset) ne marche pas?
    Par Arbiorix dans le forum Services Web
    Réponses: 2
    Dernier message: 09/12/2008, 17h17
  3. Réponses: 10
    Dernier message: 05/02/2007, 17h07
  4. [C#] ftp : pourquoi mon fichier à uploader n'est pas accessible ?
    Par LE NEINDRE dans le forum Windows Forms
    Réponses: 3
    Dernier message: 12/09/2006, 14h52
  5. Réponses: 2
    Dernier message: 12/05/2006, 23h01

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