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

SL & STL C++ Discussion :

STL Problème d'itérateur


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Par défaut STL Problème d'itérateur
    Bonjour à tous,

    Je travaille sur l'implémentation d'un projet en C++ et j'ai quelques soucis avec les iterateurs de STL (c'est la première fois que je rencontre ce genre de problème). Je l'expose.

    J'ai une classe virtuelle pure VirtClass et deux classes qui héritent de VirtClass : Class1 et Class2 !

    Ensuite, j'ai un vecteur de pointeur sur VirtClass qui contient les instances des deux classes Class1 et Class2 : vector<VirtClass*> vec;

    Lorsque je veux parcourir ce vecteur avec un iterator, impossible : la compilation se passe bien mais à l'exécution, j'ai un message d'erreur de Visual : vector iterators incompatible. Idem avec le const_iterator !

    Le pire dans tout ça, c'est que si je passe par une boucle for de i = 0 à vec.size(), ça fonctionne !!!

    Je souhaiterai comprendre pourquoi l'iterator ne fonctionne pas.
    Je vous remercie par avance.

  2. #2
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 292
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    ce que tu essaie de faire est parfaitement faisable. Il s'agit donc d'un problème dans ton code. Pourrais-tu nous le montrer?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Par défaut
    Ok,

    Voici la déclaration de VirtClass :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class VirtClass 
    {
    protected:
    	int n;
     
    public:
    	virtual void extract() = 0;
    	int getN() const { return n; }
    };
    Voici la déclaration de Class1 :

    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 Class1 : public VirtClass
    {
    protected:
    	vector<string> strs;
     
    public:
    	Class1 () 
    	Class1 (VirtClass* v) { n = v->getN(); }
     
    	~Class1 () { }
     
    	void extract() { }
    };
    Et celle de Class2 :

    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 Class2 : public VirtClass
    {
    protected:
    	vector<OtherObj*> objs;
     
    public:
    	Class2 () 
    	Class2 (VirtClass* v) { n = v->getN(); }
     
    	~Class2 () { }
     
    	void extract() { }
    };
    Ces trois classes sont sérializées avec Boost !

  4. #4
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 292
    Billets dans le blog
    2
    Par défaut
    Je ne vois pas, désolé.
    Afin d'essayer de trouver le problème, j'ai testé le code suivant, avec le niveau max pour les warning, et ça fonctionne parfaitement, sans warning.
    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
    #include <iostream>
    #include <vector>
     
    using namespace std;
     
    class VirtClass 
    {
    protected:
    	int n;
     
    public:
    	virtual void extract() = 0;
    	int getN() const { return n; }
    };
     
    class Class1 : public VirtClass
    {
    public:
    	Class1() : VirtClass() { n = 0; }
    	void extract() { cout << "extract Class1" << endl; }
    };
     
    class Class2 : public VirtClass
    {
    public:
    	Class2() : VirtClass() { n = 0; }
    	void extract() {  cout << "extract Class2" << endl; }
    };
     
    int main(int argc, char* argv[])
    {
    	vector< VirtClass*> v;
    	for ( int i = 0; i < 20; ++i )
    		if ( i%2 == 0 )
    			v.push_back( new Class1 );
    		else
    			v.push_back( new Class2 );
     
    	for ( vector< VirtClass*>::iterator it = v.begin(); it != v.end(); ++it )
    		(*it)->extract();
     
    	// nep as oublier de détruire le contenu de v sinon ya une fuite mémoire là
    	for ( vector< VirtClass*>::iterator it = v.begin(); it != v.end(); ++it )
    		delete (*it);
     
    	cin.get();
    	return 0;
    }
    Donc je ne sais pas, c'est peut-être à cause* de boost::serialize, que je ne connais pas.


    * lire "à cause d'une mauvaise utilisation de"

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Par défaut
    Ok, merci, alors, je viens d'utiliser le code fourni et ça fonctionne, je le confirme.

    Maintenant, j'ai apporté une petite modification : j'ai une classe Cont qui contient le vector<VirtClass*> vec;

    Si je mets vec en public et que j'utilise push_back pour ajouter des item, ça fonctionne. Mais dès que je le passe en private et en utilisant le getter et la méthode d'ajout, ça ne fonctionne plus :

    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
    class Cont
    {
    public:
    	vector<VirtClass*> vec;
     
    public:
    	Cont() {}
    	~Cont() {}
     
    public:	// Getters
    	vector<VirtClass*> getVec() const { return vec; }
     
    public: 
    	void addClass(VirtClass* c) { vec.push_back(c); }
    };
    Ensuite, dans le main, cc4 fonctionne et cc3 plante :

    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
     
    	Cont cc4;
    	cc4.vec.push_back(new Class1);
    	cc4.vec.push_back(new Class1);
    	cc4.vec.push_back(new Class2);
     
    	for(vector<VirtClass*>::iterator it = cc4.vec.begin(); it != cc4.vec.end(); ++it )
    		(*it)->extract();
     
     
    	Cont cc3;
    	cc3.addClass(new Class1);
    	cc3.addClass(new Class1);
    	cc3.addClass(new Class2);
     
    	for(vector<VirtClass*>::iterator it = cc3.getVec().begin(); it != cc3.getVec().end(); ++it )
    		(*it)->extract();
    Pourtant, il me semble que le getter est bon !!!

    [EDIT] : je n'utilise plus la serialization dans ces exemples !!

  6. #6
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2006
    Messages : 37
    Par défaut
    Citation Envoyé par Pg043 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public:	// Getters
    	vector<VirtClass*> getVec() const { return vec; }
    Le mot important est const.

    cc3 plante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            // [...]
    	for(vector<VirtClass*>::iterator it = cc3.getVec().begin(); it != cc3.getVec().end(); ++it )
    		(*it)->extract();
    Le mot important devrait être const_iterator.

    Et comme extract() n'est pas const tu auras une erreur ;-).

  7. #7
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,
    Citation Envoyé par N i h i l
    Le mot important est const.
    const n'est pas la cause du plantage.
    Citation Envoyé par Pg043 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<VirtClass*> getVec() const { return vec; }
    Pourtant, il me semble que le getter est bon !!!
    Non il n'est pas bon. Le problème c'est que le getter renvoie une copie de vec.
    Donc ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(vector<VirtClass*>::iterator it = cc3.getVec().begin(); it != cc3.getVec().end(); ++it )
    récupère l'itérateur begin et end sur deux copies temporaires de vec, copies qui ne sont plus valables ici :
    Un getter doit renvoyer une référence (constante ou non) sur la donnée membre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const vector<VirtClass*>& getVec() const { return vec; }

Discussions similaires

  1. Problème d'itérateur et de vecteur
    Par befast dans le forum C++
    Réponses: 1
    Dernier message: 19/10/2006, 19h47
  2. STL : problème avec un iterateur
    Par fabienpot dans le forum SL & STL
    Réponses: 4
    Dernier message: 06/09/2006, 09h06
  3. [STL]Problème avec map
    Par mambo dans le forum SL & STL
    Réponses: 11
    Dernier message: 27/07/2006, 15h39
  4. [STL]Problème itérateur avec list
    Par Fiquet dans le forum SL & STL
    Réponses: 7
    Dernier message: 03/10/2005, 17h54
  5. conteneur de la STL (problème avec DLL et COM)
    Par moldavi dans le forum MFC
    Réponses: 8
    Dernier message: 25/07/2005, 22h43

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