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 :

Utilisation iterator avec une classe perso


Sujet :

C++

  1. #1
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut Utilisation iterator avec une classe perso
    Bonjour,
    J'ai regardé le code de vector pour voir comment faire un itérateur sur sa classe.
    En fait, le code de const_iterator (j'ai pris celui là car c'est le premier...) est dans la classe. J'ai voulu sortir la définition de la classe mais ca ne fonctionne pas. Pourtant il y a bine la déclaration. pourquoi faut il mettre la définition dans la classe qui implémente l'itérateur ?

    Voici un extrait d'un code vite fait :
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    class Chaine
    {
    public:
    		Chaine(const char* ch)
    		{
    			lg=strlen(ch);
    			chaine=new char[lg+1];
    			strncpy(chaine,ch,lg);
    			chaine[lg]=0;
    		}
     
    		Chaine()
    		{
    			lg=0;
    			chaine=0;			
    		}
     
    		Chaine operator+=(const Chaine&); 
    		Chaine operator+(const Chaine&) const;
    		Chaine operator++(int);
     
    		friend ostream& operator<<(ostream& f,Chaine& c);
     
    	class const_iterator;
    	friend class const_iterator;
     
    class const_iterator
    		//: public _Ranit<_Ty, _Dift, _Ctptr, const_reference>
    {	// iterator for nonmutable vector
    	public:
    		/*typedef random_access_iterator_tag iterator_category;
    		typedef _Ty value_type;
    		typedef _Dift difference_type;
    		typedef _Ctptr pointer;
    		typedef const_reference reference;*/
     
    		const_iterator()
    			{	// construct with null pointer
    			_Myptr = 0;
    			}
     
    		const_iterator(int* _Ptr)
    			{	// construct with pointer _Ptr
    			_Myptr = _Ptr;
    			}
     
    		const_iterator& operator++()
    			{	// preincrement
    			++*_Myptr;
    			return (*this);
    			}
     
    	int* _Myptr;	// offset of element in vector
    };
     
    //private:
    	int lg;
    	char* chaine;
    };
     
    ...
    int main()
    {
    	Chaine a("A");	
    	Chaine b("B");
    	cout<<a.lg<<endl;
    	Chaine::const_iterator i(&a.lg);
    	i++;
    	cout<<a.lg<<endl<<endl;
    ...
    Et au passage, j'ai aussi 2 autres petites questions.
    Soit une class A. Quel est la différence entre les 2 lignes suivantes :
    Enfin, quelqu'un sait il pourquoi le C++ ne permet pas la surcharge du destructeur (il pourrait appeller le destructeur sans paramètre par défaut à la fin de vie d'une instance, non ?). Dans le cas d'un programme, j'aimerais bien pouvoir ne pas détruire un le contenu d'un vector pour l'utiliser dans une autre classe.
    J'aurais donc besoin de surcharger le destructeur. Sinon, je peux faire une méthode détruire qui appelle le destructeur sans détruire le contenu du vector, mais ca risque de poser des problèmes au niveau de la maintenabilité du code...

    Merci
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En fait, le code de const_iterator (j'ai pris celui là car c'est le premier...) est dans la classe. J'ai voulu sortir la définition de la classe mais ca ne fonctionne pas. Pourtant il y a bine la déclaration. pourquoi faut il mettre la définition dans la classe qui implémente l'itérateur ?
    Si j'ai bien compris, tu as essayé ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const_iterator::const_iterator()
    {
       // ...
    }
    Il ne faut pas oublier que const_iterator appartient à la classe Chaine

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Chaine::const_iterator::const_iterator()
    {
       // ...
    }
    Quel est la différence entre les 2 lignes suivantes :
    La première déclare une variable de type A, la seconde déclare une fonction ne prenant pas de paramètre et renvoyant un A. Erreur classique

    Enfin, quelqu'un sait il pourquoi le C++ ne permet pas la surcharge du destructeur (il pourrait appeller le destructeur sans paramètre par défaut à la fin de vie d'une instance, non ?). Dans le cas d'un programme, j'aimerais bien pouvoir ne pas détruire un le contenu d'un vector pour l'utiliser dans une autre classe.
    J'aurais donc besoin de surcharger le destructeur. Sinon, je peux faire une méthode détruire qui appelle le destructeur sans détruire le contenu du vector, mais ca risque de poser des problèmes au niveau de la maintenabilité du code...
    J'ai pas très bien compris ce que tu cherches à faire. Si tu souhaites que ton vector vive au dela du bloc qui le déclare, il faut en passer une copie à quelqu'un d'autre ou bien le déclarer dynamiquement (ce qui est déconseillé car c'est un peu du contre-emploi).

  3. #3
    Membre habitué Avatar de BertrandA
    Inscrit en
    Août 2003
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 170
    Points : 197
    Points
    197
    Par défaut
    pourquoi faut il mettre la définition dans la classe qui implémente l'itérateur ?
    Et à part parcourir le conteneur, à quoi d'autre peut bien servir un itérateur sur ce conteneur ?
    En outre, un itérateur "hors de la classe" devrait être déclaré comme classe amie pour accéder aux données membres du conteneur. C'est un peu bof comme choix d'implémentation.

    Soit une class A. Quel est la différence entre les 2 lignes suivantes :
    Code:
    A a1;
    A a2();
    1. Déclaration d'un objet a1 de classe A
    2. Déclaration d'une fonction a2 retournant un objet de classe A. Piège classique en C++.

    Enfin, quelqu'un sait il pourquoi le C++ ne permet pas la surcharge du destructeur
    Je ne sais pas, et je n'en vois pas vraiment l'intérêt (Ca existe dans d'autres langages objet ?). Il me semble que l'exemple que tu donnes, qui consisterait à garder en mémoire des données membres d'un objet détruit va à l'encontre des règles élémentaires de l'encapsulation.
    Les orteils servent à trouver les pieds de chaise et les montants de porte quand il fait noir.

  4. #4
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut

    Il ne faut pas oublier que const_iterator appartient à la classe Chaine

    Code:
    Chaine::const_iterator::const_iterator()
    {
    // ...
    }
    Je parlais de la classe, pas du constructeur...

    Citation:
    Quel est la différence entre les 2 lignes suivantes :
    Code:
    A a1;
    A a2();

    La première déclare une variable de type A, la seconde déclare une fonction ne prenant pas de paramètre et renvoyant un A. Erreur classique Wink
    Enfin, à force d'utiliser la première ligne, je ne me rappelais plus du sens de la deuxième...merci

    Je ne sais pas, et je n'en vois pas vraiment l'intérêt (Ca existe dans d'autres langages objet ?). Il me semble que l'exemple que tu donnes, qui consisterait à garder en mémoire des données membres d'un objet détruit va à l'encontre des règles élémentaires de l'encapsulation.
    Pas tant que ca puisque dans mon vector, je stocke des pointeurs et non pas l'objet directement...Le problème est que ca serait plus rapide d'utiliser l'objet qui est déjà construit que de faire appel à un constructeur de copie (ce que je fais pour l'instant).
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Pour la premiere question desolé, j'avais pas bien compris

    Pour eviter la recopie d'un vecteur tu peux "deplacer" les données avec swap

  6. #6
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    En fait, je sais même pas pourquoi j'y ai pas pensé avant mais j'ai un pointeur dans mon vector :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    vector<maclasse *> v;
    Suffit d'enlever le pointeur du vecteur et de le mettre dans le vecteur de l'autre classe...(s'il est pas dans le vecteur il sera pas détruit par mon destructeur...). C'est tellement évident, je sais pas pourquoi j'y ai pas pensé avant.
    Enfin je peux utiliser swap, ca fait exactement ce que je veux en fait et c portable :-) merci :-)

    Par contre, la question concernant le fait qu'il faille mettre la définition de la classe iterator dans la classe vector, je ne vois pas la réponse. Je ne suis pas sur que ca ai rapport avec l'amitié puisqu'il mettre quand même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    friend class iterator;
    Une idée ?

    Merci
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  7. #7
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    moi aussi j'avais des difficultés pour comprendre cela (j'avais posé une question il n'y pas longtemps)
    donc j'ai peut-être pour toi un début d'explication. (je ne sais pas si j'ai tout compris)

    à chaque conteneur est associé une implémentation d'un itérateur.
    c'est donc un conteneur::iterateur
    mais on peut classer ces différents types d'itérateurs suivant les propriétés qu'ils ont : InputIterator, random_access_iterator...

    ces différents catégories servent en fait dans les algorithmes de la STL :
    si un conteneur::iterateur vérifie les propriétés d'un certain type d'itérateur alors on peut utiliser l'algorithme.

    voir aussi www.sgi.com/tech/stl
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

  8. #8
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    D'accord, j'ai très bien compris ce que tu as expliqué. Ce que je voudrait savoir, c'est pourquoi ne peut on pas mettre la définition de la classe iterator en dehors de la définition de la classe qui implémente l'itérateur ?
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  9. #9
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    sans doute pour éviter de déclarer un list<char>::iterator et de l'utiliser sur un list<int>
    je ne sais pas si cela répond à ta question
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

  10. #10
    Membre émérite
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Points : 2 568
    Points
    2 568
    Par défaut
    J'ai implémenté il y a quelques années ma propre classe pile/liste et mon iterateur est placé à côté de ma class, il n'y a pas de différence !
    Sauf que c'est + "propre" de mettre ton iterator dans la class car au lieu d'avoir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class ListX
    class IteratorListX
    Tu as
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class ListX
    class ListX::Iterator
    Donc tu sais implicitement que l'Iterator à utiliser est partie intégrante de ListX et cela permet de ne pas se tromper d'Iterator, c'est tout.

  11. #11
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Effectivement, même si c'est moins "bien", rien ne t'oblige à imbriquer l'itérateur dans la classe qui va l'utiliser. Et si tu nous expliquais ton problème précisément plutôt que de répéter que ça ne marche pas ?

  12. #12
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    Nan en fait y'a pas vraiment de problèmes. J'ai bien compris tout ce que vous avez expliqué. En fait, c'était la déclaration du class iterator qui me semblait bizarre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	class const_iterator;
    	friend class const_iterator;
     
    	class const_iterator
            {
    ...
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  13. #13
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    je peux me tromper mais une classe imbriquée n'accède pas aux attributs de la classe dans laquelle elle est imbriquée. or iterator doit pouvoir manipuler les éléments de vector...
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

  14. #14
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Citation Envoyé par PINGOUIN_GEANT
    je peux me tromper mais une classe imbriquée n'accède pas aux attributs de la classe dans laquelle elle est imbriquée. or iterator doit pouvoir manipuler les éléments de vector...
    Pas forcément. En général on (le conteneur) fournit au constructeur de l'itérateur les données dont il aura besoin (un pointeur sur l'élément par exemple), et il se debrouille ensuite sans connaitre la classe qui contient les éléments sur lesquels il pointe.

  15. #15
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    je peux me tromper mais une classe imbriquée n'accède pas aux attributs de la classe dans laquelle elle est imbriquée. or iterator doit pouvoir manipuler les éléments de vector...
    J'ai compris ca !!! :-) c'est pas la question qui est :
    pourquoi la déclaration ("class const_iterator;") juste avant la définition ("class const_iterator{...};") ?

    Merci
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  16. #16
    Membre émérite
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Points : 2 568
    Points
    2 568
    Par défaut
    Et pourquoi pas ?

  17. #17
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Et qu'est-ce que ça fait si tu ne la mets pas ?

  18. #18
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    Ca ne change rien dans le cas de mon programme...Ce qui m'ammène donc à me demander pourquoi est-ce qu'ils l'ont mis ?
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  19. #19
    Membre émérite
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Points : 2 568
    Points
    2 568
    Par défaut
    Parfois il n'y a pas d'explication...

    Cela peut petre une "clarté" du code, ou une habitude du programmeur...

  20. #20
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	class const_iterator;
    	friend class const_iterator;
     
    	class const_iterator
            {
    ...
    si j'ai bien compris, ce code est à l'intérieur d'une classe.
    donc queston : le fait de déclarer la classe à l'intérieur de d'une classe impose-t'elle la définition de la classe dans celle-ci ?
    je pense que oui à cause des histoires de portées de résolution

    donc sans class const_iterator il est peut-être possbile de définir une classe const_iterator qui sera donc amie et donc on se sera fait avoir.
    cela reste une hypothèse.
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

Discussions similaires

  1. Réponses: 2
    Dernier message: 20/05/2010, 11h06
  2. [WPF] Problème de binding avec une classe perso
    Par JuTs dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 12/04/2010, 18h45
  3. Utiliser les méthodes ror dans une class perso
    Par BakaOnigiri dans le forum Ruby on Rails
    Réponses: 10
    Dernier message: 01/02/2010, 12h01
  4. template et utilisation avec une classe existante
    Par vartav dans le forum Langage
    Réponses: 6
    Dernier message: 14/03/2007, 10h39
  5. pb utilisation d'une classe perso
    Par sharivaree dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 14/12/2006, 18h44

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