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 :

[list::iterator] une liste d'iterator


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Par défaut [list::iterator] une liste d'iterator
    Bonjour, Bon, je pensais avoir compris les conteneurs, mais voila, ca ne marche pas comme je le veux.
    Voici exactement mes declarations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class CCell;
    typedef std::list<CCell> TCellsList;
    typedef TCellsList::iterator TIteratorOnACell;
    typedef std::list<TIteratorOnACell> TiterCellsList;
    typedef TiterCellsList::iterator TIteratorOnAniterCell;
    Ce que je veux faire ? :
    j'ai une classe CCell, je veux avoir une list d'instances de CCell => TCellsList.
    TIteratorOnACell est mon outil de parcours de ma liste de CCell.

    Avant de détailler la suite, je vous explique l'objectif recherche :
    J'ai une liste de cellules "generale". Et je veux pouvoir distinguer au sein de cette liste, des sous-listes. Mais je ne veux pas creer de doublons de cellules. Donc, je m'etais dis, mes sous-ensembles doivent etre des liste de pointeur faisant reference a un element de ma liste generale. Ca va, tous le monde me suit ? A ce moment la, je me suis dis, bon, les iterateurs, ce sont des pointeurs !!! Donc si je fais une liste d'iterateurs ... Et c'est la je pense qu'est mon erreur.
    TiterCellsList c'est ma liste d'iterateurs. (mes sous-ensembles)
    TIteratorOnAniterCell mon outil de parcours d'un sous-ensemble.

    Maintenant, je remarque que :
    - je parcours ma liste generale de cellule sans probleme, les donnees, tout est correcte.
    - je parcours une sous liste, le nombre d'element est correcte mais les donnees c'est n'importe quoi !

    J'ai bien verifie ma procedure d'ajout d'elements d'une sous liste et je n'y vois rien de speciale. J'en conclu que l'utilisation des listes d'iterateurs est une erreur, surement parceque ceux ci sont ephemeres et que je perds la liaison avec l'element de la liste generale. Le solution serait donc de faire une liste de bon vieux pointeurs !

    Je sais comment regler le pb, a priori. Mais cette histoire me titille alors est ce que vous pourriez me confirmer ou imfirmer mes soupcons pour ma culture svp, et surtout pour etre sur de bien comprendre, cette fois ci le fonctionnement des iterateurs.

    merci d'avance pour vos reponses.

  2. #2
    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
    Citation Envoyé par kase74 Voir le message
    J'en conclu que l'utilisation des listes d'iterateurs est une erreur, surement parceque ceux ci sont ephemeres et que je perds la liaison avec l'element de la liste generale.
    Les itérateurs ne sont pas fait pour être 'maintenus'. Ils peuvent changer dès que tu modifies ta liste (par ajout ou suppression).

    Citation Envoyé par kase74 Voir le message
    Le solution serait donc de faire une liste de bon vieux pointeurs !
    Pas forcément (en plus cela risque d'introduire autant de problème que ça n'en résoud). Cela dépend du critère de tes sous-listes. Tu peux utiliser par exemple des itérateurs boost, type filter_iterator pour reconstituer ta liste. En fait, l'idée serait plutôt de travailler sur des 'filtres' pour tes différentes sous-listes.

  3. #3
    Membre éclairé
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Par défaut
    Bonjour 3DArchi, merci pour ta reponse.

    Tu me dis qu'il risque d'y avoir plus de problemes avec les pointeurs, mais lesquels, je ne vois pas pourquoi ?

    Je vais regarder comment fonctionnent les iterateurs de filtre, je ne les connais pas.

  4. #4
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Parce qu'en C++ on évite le plus possible d'utiliser les pointeurs. Plus t'en a plus tu as des risques de segfault et autres joyeuseté.
    Ou alors utilisé des pointeurs 'enrobé', les smart pointeurs.

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Les itérateurs ne sont pas fait pour être 'maintenus'. Ils peuvent changer dès que tu modifies ta liste (par ajout ou suppression).
    C'est faux. Tu confonds vector et list. Seul assign invalide les itérateurs.

    Ensuite j'ai du mal à voir comment un itérateur définit un sous-ensemble. Il faudrait une paire d'itérateurs (en supposant qu'il n'y a pas de "trou" dans le sous-ensemble).

  6. #6
    Membre éclairé
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Par défaut
    Bonjour, merci pour vos reponses.

    Citation Envoyé par loufoque Voir le message
    C'est faux. Tu confonds vector et list. Seul assign invalide les itérateurs.
    Ca veut dire que ca peut marcher mon principe ?

    Citation Envoyé par loufoque Voir le message
    Ensuite j'ai du mal à voir comment un itérateur définit un sous-ensemble. Il faudrait une paire d'itérateurs (en supposant qu'il n'y a pas de "trou" dans le sous-ensemble).
    Un iterateur ne defini pas un sous ensemble mais juste un element CCell. C'est une liste d'iterateur qui definie mon sous ensemble.

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par loufoque Voir le message
    C'est faux. Tu confonds vector et list. Seul assign invalide les itérateurs.
    Et erase invalide évidemment les itérateurs sur les éléments supprimés.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    Je verrais 2 manières gérer ton problème.

    Tu pourrais gérer les objets dynamiquement, avec des vector de pointeurs, à condition d'encaspuler ces traitements dans une classe pour assurer une certaine sécurité, RAII et tout ça. De cette manière les sous-listes pourraient se référer aux objets eux-même plutôt qu'à des iterateurs sur les objets.
    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
     
    vector<CCell*> generic;
    vector<CCell*> specific1;
    vector<CCell*> specific2;
     
    CCell* pC = new CCell(type1);
    generic.push_back(pC);
    specific1.push_back(pC);
     
    pC = new CCell(type2);
    generic.push_back(pC);
    specific2.push_back(pC);
     
    specific2.clear();
    specific1.clear();
    for(vector<CCell*>::iterator it = generic.begin(); it!=generic.end(); ++it)
        delete (*it); // Récupérer le pointeur pour deleter l'objet pointé;
    generic.clear();
    Mais pour être vraiment prudent, il vaut mieux encapsuler la liste générique dans une autre classe, qui assure l'effacement correct des objets, notamment en cas d'erreur.
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    class CCellManager
    {
    private:
        vector<CCell*> _list;
    public:
        ~CCellManager(){ // Suppression du contenu dynamique par le destructeur
           clear(); // Evite la duplication de code
        }
     
        void clear(){
             for(vector<CCell*>::iterator it = _list.begin(); it!=_list.end(); ++it)
                delete (*it);
            _list.clear();
        }
     
        vector<CCell*>::iterator begin() { return _list.begin(); }
    /* On pourrait même masquer le fait qu'on gère avec un vector en renvoyant
     plutôt une itérateur "maison", ou avec un typedef :
    typedef vector<CCell*> cm_list; 
    cm_list::iterator begin() { return _list.begin(); }
    pour pouvoir éventuellement modifier l'implémentation.
    */
     
        vector<CCell*>::iterator end(); { return _list.end(); }
     
        void push_back(CCell* C) { _list.push_back(C); }
     
        void erase(CCell* C) {
            for(<vector<CCell*>::iterator it = _list.begin; it!=_list.end(); ++it)
                if((*it) == C){
                    delete (*it); // Ou : delete C;
                    _list.erase(it);
                    break;
                }
        }
    };
     
    // Utilisation:
     
    int main(){
        CCellManager cm;
        cm.push_back(new CCell());
        cm.push_back(new CCell());
     
        for(vector<CCell*>::it = cm.begin(); it!=cm.end(); ++it)
            (*it)->do_something(); // Ce genre d'écriture est toutefois un peu lourde, et sujete à erreur, il faut bien l'admettre.
     
        cm.clear();
     
        cm.push_back(new CCell());
     
        return 0; // A la sortie de la fonction, le destructeur de cm évitera la fuite mémoire
    }
    Bon, c'est juste un premier jet pour donner une idée, ce serait à affiner en fonction de ta conception, on peut certainement faire une interface plus intuitive. De plus, il faudrait se replonger dans la spécification des vecteurs, mais il est peut-être possible de faire ça sans utiliser de pointeurs, si les vecteurs instancient leurs objets une fois et ne les déplacent pas, par exemple si on ajoute ou retire des objets. Peut-être quelque chose comme ça:
    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
     
    vector<CCell> generic;
    vector<CCell*> specific1;
    vector<CCell*> specific2;
     
    generic.push_back(CCell(type1));
    generic.push_back(CCell(type2));
     
    for(vector<CCell*>::iterator it = generic.begin(); it!=generic.end(); ++it){
        if(it->critere_de_repartition() == type1) specific1.push_back(&(*it)); // Adresse de l'objet pointé par l'itérateur
        else if (it->critere_de_repartition() == type2) specific2.push_back(&(*it));
    }
     
    specific2.clear();
    specific1.clear();
    Un autre idée : si tous les objets de la liste générale sont forcément membres d'une sous-liste ou d'une autre, tu pourrais gérer le cycle de vie des objets dans tes sous-listes, et la liste générale serait un itérateur qui passerait en revue les différentes sous-listes.

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

Discussions similaires

  1. [Lisp][IA] Supprimer une liste d'une liste de listes
    Par Superleo2999 dans le forum Lisp
    Réponses: 5
    Dernier message: 22/03/2010, 10h51
  2. champ d'une liste lié à une liste dans un autre site
    Par guintolli dans le forum SharePoint
    Réponses: 8
    Dernier message: 08/07/2008, 14h51
  3. [PRBL]Caste une liste d'une liste d'objet
    Par stephane92400 dans le forum Langage
    Réponses: 4
    Dernier message: 07/08/2007, 21h01
  4. Appel d'une liste dans une liste (JSTL)
    Par abalgue dans le forum Hibernate
    Réponses: 4
    Dernier message: 15/06/2007, 10h56
  5. STL : retirer une liste d'une liste
    Par DEVfan dans le forum SL & STL
    Réponses: 13
    Dernier message: 05/01/2007, 20h49

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