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 :

vInt::iterator


Sujet :

C++

  1. #1
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut [résolu] vInt::iterator
    étant donné que j'ai besoin de dériver, que vector n'a pas de destructeur virtuel, et que j'ai besoin de fonctions membres supplémentaires, j'ai besoin de creer une classe vInt, avec la même interface (réduite) que vector. J'ai donc commencé ainsi :

    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
    #include <vector>   
     
    using namespace std; 
     
     
    class vInt // c'est un vector<int> avec des fonctions supplémentaires
    {
    vector<int>* VectInt;
     
    public:
     
    	virtual vInt()
    	{
    		VectInt=new vector<int>
    	}
     
    	virtual ~vInt()
    	{
    		VectInt=delete vector<int>
    	}
     
    	virtual void push_back(int n)
    	{	
    		VectInt.push_back(n);
    	}
     
    	virtual void clear()
    	{
    		VectInt.clear();
    	}
    Jusqu'ici, tout va bien. Enfin, je crois. C'est apres que j'ai un problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	vInt::iterator begin()
    	{
    		return(VectInt.begin());
    	}
    En effet, je ne sais pas du tout comment définir un vInt::iterator. Alors que j'en ai besoin un petit peu partout. Quelqu'un saurai m'aider svp ? :o)

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Qu'est ce qui t'empêche de reprendre simplement vector::iterator ?
    Oups...
    -

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 28
    Points : 32
    Points
    32
    Par défaut
    Coucou,

    En reprenant le problème à la base, tu peux faire une classe dérivé puisque la destruction d'un objet passe par la destruction des parties héritées de manière automatique.

    Cependant cela veut dire que les occurences de ta classe dérivée ne seront crées que en tant que tel, et non pas en tant que vector.

    Si je me plante, dites le moi :
    mieux se savoir ridicule une fois que de l'être toujours sans jamais le savoir

    Sinon je suis d'accord avec Christophe, rien ne t'empèche d'utiliser un vector::iterator.
    Fëanor13 alias Marmotte
    "An eye for an eye makes the whole world blind." - Gandhi -
    Je suis une quiche en Anglais, alors merci de ne pas me renvoyer sur des sites anglophones...
    Merci

  4. #4
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    Etant donné que le destructeur de vector n'est pas virtuel, je ne peux pas faire de classe dérivée à partir de vector :
    http://www.developpez.net/forums/viewtopic.php?t=67486
    (j'aurai éventuellement ensuite à faire un vTruc avec un Truc un peu moins simple qu'un int)

    Quant à l'utilisation de vector<int>::iterator, ben je pourrai l'utiliser, mais je veux une "interface propre". C'est à dire que si je travaille avec un vInt, j'utilise un vInt::iterator...

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Pas de problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class vInt
    {
      public :
      typedef vector< int >::iterator iterator;
      typedef vector< int >::const_iterator const_iterator
      // etc..
    };
    Dans la mesure où ton itérateur n'est jamais qu'un vector< int >::iterator, cela suffit à la propreté de l'interface. Si jamais par la suite, pour une raison quelconque, tu as besoin de spécialiser le comportement de l'itérateur, alors tu pourras toujours développer la classe idoine pour encapsuler ton itérateur et modifier le typedef pour garantir la cohérence de l'interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class vInt
    {
      class vIntIterator 
      { 
      // ...
      };
     
      public :
      typedef vIntIterator iterator;
      typedef const iterator const_iterator;
      // etc..
    };
    Oups...
    -

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Christophe a raison a un detail pres : le typename
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class vInt
    {
      public :
      typedef typename vector< int >::iterator iterator;
      typedef typename vector< int >::const_iterator const_iterator
      // etc..
    };
    voila, certain compilo s'en foutent mais pas tous !

  7. #7
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    oki, merci beaucoup :o)

    J'ai encore beaucoup de chapitre à lire et d'expérience à acquérir avant de faire tout ce que je veux, heureusement que vous êtes là :o)

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Citation Envoyé par Gandalf
    Christophe a raison a un detail pres : le typename
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class vInt
    {
      public :
      typedef typename vector< int >::iterator iterator;
      typedef typename vector< int >::const_iterator const_iterator
      // etc..
    };
    voila, certain compilo s'en foutent mais pas tous !
    Ha justement, ta remarque tombe à pic !
    J'ai vu traîner par-ci par-là des typename (sans typedef devant en général) et je n'ai jamais pu me faire une idée précise de ce que cela changeait par rapport au typedef.
    : Pourrais-tu éclairer ma lanterne là-dessus ?
    Oups...
    -

  9. #9
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    tiens, puisqu'on est lancé, je n'arrive pas à coder l'operator[]

    Voilà ce que j'ai écrit :
    le début de ma classe :
    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
     
    class vInt // c'est un vector<int> avec des fonctions supplémentaires
    {
    	vector<int>* VectInt; 
     
    public:
    	vInt() 
    	{ 
    		VectInt=new vector<int>; 
    	} 
     
    	virtual ~vInt() 
    	{ 
    		delete VectInt;
    	} 
     
    	typedef vector< int >::iterator iterator; 
    	typedef vector< int >::const_iterator const_iterator;
    et voici les 2 essaies que j'ai fait pour coder l'operator :
    celui qui me semblait le plus propre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	int& vInt::operator[](unsigned int n)
    	{
    		VectInt->operator[](n);
    	}
    et un autre que j'ai tenté puisque le premier ne marchait pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	int& vInt::operator[](unsigned int n)
    	{
    		vector<int>::iterator p=VectInt->begin();
    		p+=n;
    		return(*p);
    	}
    et aucun des 2 ne marche...

    et sinon, le typedef/typename m'interesse aussi :o)

  10. #10
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Citation Envoyé par Christophe Brun
    Ha justement, ta remarque tombe à pic !
    J'ai vu traîner par-ci par-là des typename (sans typedef devant en général) et je n'ai jamais pu me faire une idée précise de ce que cela changeait par rapport au typedef.
    : Pourrais-tu éclairer ma lanterne là-dessus ?
    typename indique simplement que ce qui suit est un type, rien de plus.

    les cas d'utilisation sont toujours liés aux templates

    ex1 dans la declaration des templates il peut remplacer class



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template < [b] typename toto[/b] >
    est equivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template < [b]class toto[/b]>
    Sinon il doit etre utilise chaque fois que tu reference un type dans une classe template, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typename vector<int>::iterator
    Donc rien a voir avec le typedef... sauf quand on veux definir un nouveau type a partir d'un type provenant d'un template ;-)

    Ceci est particulierement vrai quand le template n'est pas resolu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template <class T>
    class titi
    {
       ....
       typedef typename vector<T>::iterator iterator;
       ....
    };
    VC6 est plutot gene par les typename, gcc 2.96 semble s'en contre-foutre par contre le compilo HP est très a cheval dessus...

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Ref : Gandalf.
    Vu ! J'avais eu quelques soucis de compilations avec ces problèmes. Voilà qui est plus clair pour moi, à présent !

    Ref : Velu.
    Que veux-tu dire par 'ne marche pas' ? Est-ce que ça ne compile pas, où est-ce que les résultats ne sont pas bons ?

    En ce qui concerne l'utilisation de l'opérateur +=, ça ne devrait pas compiler. std::vector::iterator ne connait que operator++(...) et operator--(...)
    Donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    vector< int > vct;
    // ... initialisations
    vector< int >::iterator it( vct.begin() );
    it += 5; // ... ne compile pas
    for ( int i = 0; i < 5 ; ++ i ) ++ it; // ... est ok
    En ce qui concerne l'operator [], ça devrait compiler, et plus si affinités. Il doit y avoir un pépin ailleurs dans ton code.
    En cas de doute, tu peux essayer de bidouiller à partir du code suivant (qui marche )
    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
     
    int& vctF( int idx, vector< int >* pvct )
    {
      vector< int >* pvct = new vector< int >;
     
      // Initialisation bidon...
      for ( int i = 0; i <= idx; ++ i )
      {
        pvct->push_back( i );
      }
     
      return pvct->operator []( idx );
    }
     
    int main()
    {
      vector< int >* pvct = new vector< int >;
      // initialisation bidon...
      for ( int i = 0; i < 5; ++ i )
      {
        pvct->push_back( i );
      }
     
      // visualisation sur la console, pour 
      // les sceptiques invétérés
      copy( pvct->begin(), pvct->end(), ostream_iterator< int, char >( cout, " " ) );
      cout << endl;
     
      // utilisation de l'operator litigieux
      pvct->operator []( 2 ) = 10;
     
      // re-visualisation...
      copy( pvct->begin(), pvct->end(), ostream_iterator< int, char >( cout, " " ) );
      cout << endl;
     
      // deuxième utilisation : operator[] est planqué 
      // dans une fonction. Saurez-vous le faire 
      // sortir de sa tanière...?
      vector< int > vct2;
      cout << vctF( 5, &vct2 );
    }
    Tu y trouves deux contextes d'utilisation pour operator[] : utilisation directe la première fois dans le main, encapsulation avec renvoi de réference en dans vctF(). Le contexte de ton problème devrait approximativement s'apparenter à l'un de ceux-là.
    Courage, Petit Scarabée. Je sens que tu es sur la bonne Voie ! 8)
    Oups...
    -

  12. #12
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Normalement les iterateur de vector sont des iterateurs random donc ils devraient supporter les operateurs += et -=
    Tout comme ceux de la deque.

    http://www.sgi.com/tech/stl/RandomAccessIterator.html

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Ha oui, tiens ! J'ai parlé trop vite. Autant pour moi...
    Oups...
    -

  14. #14
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    Oui, ca compile. Mais mon programme crashe ensuite, alors que je n'ai rien changé par rapport au moment ou je dérivais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class vInt: public vector<int> {} // ca, c'était avant
    Je n'ai rien changé au programme depuis que j'écrit mon propre vInt avec un vector<int> comme membre, donc j'aurai aimé que ca fonctionne de la même manière ;o)

    En fait, le problème ne vient peut-être pas du vInt...

    ca compile tres bien, mais il crashe. J'ai lancé le débogueur, et il me dit :
    Citation Envoyé par VC++
    Loaded 'ntdll.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\system32\kernel32.dll', no matching symbolic information found.
    First-chance exception in CPPpersoADD.exe: 0xC0000005: Access Violation.
    et il me renvoie à un endroit de la STL...

    voilà l'endroit ou il semble planter :
    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
     
    	InterfaceConsoleADD& Carac()
    	{
     
    		// Je propose les jets de dés habituels :
    		cout << "Voulez vous une série de lancer de dés selon les règles ? (O/N)";
    		bool loop; // il plante ici
    		loop=confirm();
    		if(loop)
    		{
    			do
    			{
    				cout << "tirage : ";
    				Des unde(6);
    				for(int k=0;k<6;k++)
    				{
    					cout << unde.TsQ() << " - ";
    				}
     
    			cout << "Preferez-vous un nouveaux tirage ? (O/N)";
    				loop=Confirm();
    			}
    			while(loop);
    		}
    et il me renvoit à cet endroit de la STL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template <bool __threads, int __inst>
    void _STLP_CALL
    __node_alloc<__threads, __inst>::_M_deallocate(void *__p, size_t __n) {
      _Obj * _STLP_VOLATILE * __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);
      // #       ifdef _STLP_THREADS
      /*REFERENCED*/
      _Node_Alloc_Lock<__threads, __inst> __lock_instance;
      // #       endif /* _STLP_THREADS */
      // acquire lock
      ((_Obj *)__p) -> _M_free_list_link = *__my_free_list; // le débogueur me signale cette ligne
      *__my_free_list = (_Obj *)__p;
      // lock is released here
    }
    avec l'erreur suivante :

    Mais là, j'avoue que j'y comprends pas tout ;o)

    Enfin, celà peut-il venir de mon processeur ? Il a pas mal eu de surchauffe ces derniers temps, ainsi qu'une probable sous-alimentation prolongée... Ca a occasionné pas mal de crash, c'est stabilisé là, mais peut-être le processeur est-il endommagé... ? Parceque j'ai eu la même "acces violation" avec d'autre logiciel que je n'avait pas écrit (et les autres utilisateurs n'avaient pas ce problème).

    Enfin, je ne sais trop que faire...

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Ton bug ressemble assez à un problème d'écrasement de mémoire. L'ennui avec ce genre de choses est que le comportement du logiciel est imprévisible : ça peut planter avec un code donné et marcher quand tu ajoutes un point virgule quelque part...

    Tu devrais tester ta classe vInt en dehors de ton programme ADD. Le mieux est de coder un petit banc de test dans lequel tu secoues ton vector en tous sens (copie, insertions, affectations, retrait, accès en multithread si ton app est multithreadée, bref, tout ce que tu peux imaginer pour le faire planter). S'il passe le banc de test, tu pourras être assez confiant dans cette classe et aller voir ailleurs.
    La stratégie du banc de test peut s'appliquer à la plupart des classes et des méthodes. Il est conseillé de l'utiliser souvent (tester chaque nouvelle méthode et chaque nouvelle classe, sauf quand on est VRAIMENT sûr de son coup). En outre, c'est un excellent exercice pour préciser les spécifications d'une classe en développement.
    Oups...
    -

  16. #16
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    j'ai testé mon nouveau vInt, et je ne lui trouve pas d'erreurs... Cependant, je ne sais pas si je teste réellement tout (d'ailleurs, si je testais réellement out, j'aurai surement trouvé l'erreur)

    Voilà le nouveaux vInt :
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
     
    #include <vector>   
     
    using namespace std; 
     
    class vInt // c'est un vector<int> avec des fonctions supplémentaires
    {
    	vector<int>* VectInt; 
     
    public:
     
    	vInt() // constructeur
    	{ 
    		VectInt=new vector<int>; 
    	} 
     
    	virtual ~vInt() // destructeur
    	{ 
    		delete VectInt;
    	} 
     
    	typedef vector< int >::iterator iterator; 
    	typedef vector< int >::const_iterator const_iterator;
     
    	void push_back(int n) //
    	{	
    		VectInt->push_back(n);
    	}
     
    	void clear() //
    	{
    		VectInt->clear();
    	}
     
    	vInt::iterator begin() //
    	{
    		return(VectInt->begin());
    	}
     
    	vInt::iterator end() //
    	{
    		return(VectInt->end());
    	}
     
    	void affiche() // affichage des vInt sur les consôles (pour le débogage)
    	{
     
    		for(vInt::iterator p = VectInt->begin(); p!= VectInt->end();p++)
    		{
    			cout << *p << ' ';
    		}
    	}
     
    	int Max() // renvoie le int le plus haut d'un vInt
    	{
    		int max;
    		vInt::iterator p=VectInt->begin();
    		max=(*p);
     
    		for(;p!=VectInt->end();p++)
    		{
    			if(max<(*p))
    			{
    				max=(*p);
    			}
    		}
    		return max;
    	}
     
    	vInt& vInt::operator*=(int val) //
    	{
    		for(vInt::iterator p = VectInt->begin();p != VectInt->end();p++)
    		{
    			*p=(*p)*val;
    		}
    		return *this;
    	}
     
    	vInt& vInt::operator+=(vInt &vct) //
    	{
    		vInt::iterator p = VectInt->begin();
    		vInt::iterator q = vct.begin();
     
    		while( p != VectInt->end() && q != vct.end())
    		{
    			*p+=*q;
    			p++;
    			q++;
    		}
    		return *this;
    	}
     
    	vInt& vInt::operator=(vInt &vct) //
    	{
    		VectInt->clear();
    		vInt::iterator q = vct.begin();
     
    		while(q != vct.end())
    		{
    			VectInt->push_back(*q);
    			q++;
    		}
    		return *this;
    	}
     
     
    	vInt& vInt::operator-=(vInt &vct) //
    	{
    		vInt::iterator p = VectInt->begin();
    		vInt::iterator q = vct.begin();
     
    		while( p != end() && q != vct.end())
    		{
    			*p-=*q;
    			p++;
    			q++;
    		}
    		return *this;
    	}
     
    	vInt& vInt::operator=(int val) //
    	{
    		for(vInt::iterator p = VectInt->begin();p != VectInt->end();p++)
    		{
    			*p=val;
    		}
    		return *this;
    	}
     
    	int& vInt::operator[](unsigned int n) //
    	{
    		vector<int>::iterator p=VectInt->begin();
    		p+=n;
    		return(*p);
    	}
     
    	unsigned int vInt::size() //
    	{
    		return(VectInt->size());
    	}
     
    };
    Et voici l'ancien :
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    #include <vector>   
     
    using namespace std; 
     
     
    class vInt: public vector<int> // c'est un vector<int> avec des fonctions supplémentaires
    {
     
    public:
    	vInt& vInt::operator=(vInt &vct) //
    	{
    		clear();
    		vInt::iterator q = vct.begin();
     
    		while(q != vct.end())
    		{
    			push_back(*q);
    			q++;
    		}
    		return *this;
    	}
     
    	vInt& vInt::operator+=(vInt &vct) //
    	{
    		vInt::iterator p =     begin();
    		vInt::iterator q = vct.begin();
     
    		while( p != end() && q != vct.end())
    		{
    			*p+=*q; //
    			p++;
    			q++;
    		}
    		return *this;
    	}
     
    	vInt& vInt::operator-=(vInt &vct) //
    	{
    		vInt::iterator p =     begin();
    		vInt::iterator q = vct.begin();
     
    		while( p != end() && q != vct.end())
    		{
    			*p-=*q;
    			p++;
    			q++;
    		}
    		return *this;
    	}
     
    	vInt& vInt::operator*=(int val) //
    	{
    		for(vector<int>::iterator p = begin();p != end();p++)
    		{
    			*p=(*p)*val;
    		}
    		return *this;
    	}
     
    	vInt& vInt::operator=(int val) //
    	{
    		for(vInt::iterator p = begin();p != end();p++)
    		{
    			*p=val;
    		}
    		return *this;
    	}
     
    	void affiche() //
    	{
     
    		for(vInt::iterator p = begin(); p!= end();p++)
    		{
    			cout << *p << ' ';
    		}
    	}
     
    	int Max() //
    	{
    		int max;
    		vInt::iterator p=begin();
    		max=(*p);
     
    		for(;p!=end();p++)
    		{
    			if(max<(*p))
    			{
    				max=(*p);
    			}
    		}
    		return max;
    	}
    };
    Mon programme marche tres bien si j'include l'ancien, mais il ne marche pas avec le nouveaux (crash en plein milieu) et je ne trouve pas d'où celà vient...

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Bon, ça m'a l'air à peu près correct, tout ça !

    La seule erreur que je voie est qu'il manque un constructeur par recopie. Ta classe vInt possède un pointeur sur un vector< int > qu'elle libère dans son destructeur. Si jamais un vInt est construit par recopie à partir d'un autre vInt, ce pointeur sera recopié et il y aura donc 2 pointeurs pointant sur le même bout de mémoire. Le premier des deux vInt fera un delete sur son pointeur et invalidera le bloc mémoire toujours pointé par le pointeur du second vInt, ce qui induira tôt ou tard à des comportements erratiques.

    Essaye avec cette correction pour voir. Sinon, mets-nous en ligne le code qui plante pour la suite de l'enquête.

    Quelques chipotis au passage :

    1 -
    Tu peux passer des arguments à une méthode par référence quand ces arguments doivent (ou peuvent) être modifiés dans la méthode. Sinon, il est plus clair et plus sûr de dire au compilateur (et au lecteur du code) : "attention, je fais une référence pour économiser une copie, mais cet argument ne doit pas être modifié". Et pour dire cela, il suffit de paser une référence constante (et dans le cas de tes méthodes, d'utiliser dans celles-ci des const_iterators).
    Ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    vInt& vInt::operator=( const vInt& vct );
    vInt& vInt::operator-=( const vInt& vct );
    etc...
    2 -
    Il vaut mieux faire ++p que p++, ça fait une copie de moins.
    Il vaut mieux stocker les variables calculées non susceptibles d'être modifiées, ça limité les calculs.
    Ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for( vInt::iterator p = VectInt->begin(), end = VectInt->end(); p!= end;++ p ) ...
    Je sais bien que l'iterator de vector est souvent un simple pointeur, mais souvent signifie 'pas toujours'. En outre, les itérateurs des autres conteneurs sont susceptibles d'être beaucoup plus lourds. C'est donc une habitude à prendre qui ne coûte rien, et qui peut économiser pas mal de cycles, en particulier dans les boucles.

    3 -
    J'ose à peine te le dire de peur de te contrarier, mais... les méthodes que tu as ajoutées à vInt existent dans la STL, au rayon des algorithmes.
    Je n'ai pas le temps de détailler cela tout de suite , mais jette un oeil à copy, transform, for_each pour commencer.
    Un exemple tout de même en vitesse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    vector< int > vctInt;
     
    // pour void affiche();
    copy( vctInt.begin(), vctInt.end(), ostream_iterator< int, char >( cout, " " ) );
    Allez hop, je file.
    Bonne journée !
    Oups...
    -

  18. #18
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    1-

    J'avais essayé les const vInt &vct, mais ca n'avait pas été concluant, et j'ai toujours la même erreur (8 fois la même en fait, je prend un exemple pour illustrer) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	vInt& vInt::operator-=(const vInt &vct) //
    	{
    		vInt::iterator p = VectInt->begin(), end=VectInt->end();
    		vInt::const_iterator q = vct.begin(), endc=vct.end(); // c'est cette ligne, la 123
     
    		while( p != end && q != endc)
    		{
    			*p-=*q;
    			p++;
    			q++;
    		}
    		return *this;
    	}
    Citation Envoyé par VC++
    f:\c\cpppersoadd\vint2.h(123) : error C2662: 'begin' : cannot convert 'this' pointer from 'const class vInt' to 'class vInt &'
    Conversion loses qualifiers
    2- oui, oui, tu as raison :o) J'essaie de plus en plus de le faire, stocker ce qui ne change pas jusqu'à la fin du calcul pour éviter de le recalculer :o)

    3- à vrai dire, j'ai pas encore regardé les algorithmes. Il y a déjà tellement de chose que je n'ai pas regardé et qui me semblent plus importante :o)
    Sinon, pour affich(), cette version là est celle qui me sert à déboguer (à chaque fois que j'ai un doute sur le contenu du vecteur, je met un ce_vecteur-louche.affich() dans mon code, ou que ce soit, et je vois ce qu'il contient réellement. J'envisage ensuite de le "muscler" avec des paramètres un peu plus précis (largeur, mise en forme, etc...). Mais c'est vrai que dans ce cas, j'aurai pu utilisé ce que tu proposes si j'avais su l'utiliser ;o)

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Citation Envoyé par Monstros Velu
    f:\c\cpppersoadd\vint2.h(123) : error C2662: 'begin' : cannot convert 'this' pointer from 'const class vInt' to 'class vInt &'
    Conversion loses qualifiers
    Ha oui, c'est normal. Un objet const ne peut utiliser que celles de ses méthodes qui ont été déclarées const. Dans ton vInt, ce n'est le cas d'aucune d'entre elles, donc tes vInt const ne sont pas utilisables.
    Si tu ajoutes par exemple une version const pour begin() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    vInt::const_iterator begin() const
       { 
          return(VectInt->begin()); 
       }
    l'erreur de compilation pour begin() disparaîtra. Reste à traiter à l'identique celles des autres méthodes qui ne modifient pas l'état interne de l'objet, donc qui méritent le qualificatif const.

    D'une manière générale, toute méthode pouvant être déclarée const doit être déclarée const. Cela permet declarifier l'interface, de détecter des erreurs d'utilisation à la compilation et d'utiliser pleinement le qualificatif (et la sécurité) du const.

    NB : certaines méthodes n'ont pas besoin d'avoir une version const et une version non const. vInt::begin() a les deux versions car le type de retour diffère. Par contre, vInt::Max() peut très bien n'être déclarée qu'en version const.
    Oups...
    -

  20. #20
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut Ca y est ca marche ! :o)
    bon, ca marche... j'ai enlevé le pointeur pour le remplacer directement par l'objet correspondant... et depuis, ca marche ;o)

    Voilà, si ca amuse qq1 de critiquer mon code, j'écoute :o)

    vint.h :
    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
    #ifndef __VINT_H
    #define __VINT_H
     
    #include <vector> 
    #include <iostream>
     
    //bon, on retente un coup sans dériver
     
    using namespace std; 
     
    class vInt // c'est un vector<int> avec des fonctions supplémentaires
    {
    	vector<int> VectInt; 	
    public:
    	typedef vector< int >::iterator iterator; 
    	typedef vector< int >::const_iterator const_iterator;
    	vInt(); // constructeur 
    	vInt(const vInt& vct); // constructeur par copie
    	virtual ~vInt(); // destructeur
    	void push_back(int n); //
    	void clear(); //
    	vInt::iterator begin(); //
    	vInt::const_iterator begin() const; //
    	vInt::iterator end(); //
    	vInt::const_iterator end() const; //
    	void affiche(); // affichage des vInt sur les consôles (pour le débogage)
    	int Max(); // renvoie le int le plus haut d'un vInt
    	vInt& vInt::operator*=(int val); //
    	vInt& vInt::operator+=(vInt &vct); //
    	vInt& vInt::operator=(vInt &vct); //	
    	vInt& vInt::operator-=(vInt &vct); //
    	vInt& vInt::operator=(int val); //
    	int& vInt::operator[](unsigned int n); //
    	unsigned int vInt::size(); //
    };
     
    #endif
    et vint.cpp
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
     
    #include "vint.h"
     
     
    vInt::vInt() // constructeur
    { 
    } 
     
    vInt::vInt(const vInt& vct) // constructeur par copie
    {
    	for(vector<int>::const_iterator p=vct.begin(), end=vct.end();p!=end;++p)
    	{
    		VectInt.push_back(*p);
    	}
    }
     
    vInt::~vInt() // destructeur
    { 
    } 
     
    void vInt::push_back(int n) //
    {	
    	VectInt.push_back(n);
    }
     
    void vInt::clear() //
    {
    	VectInt.clear();
    }
     
    vInt::iterator vInt::begin() //
    {
    	return(VectInt.begin());
    }
     
    vInt::const_iterator vInt::begin() const //
    { 
    	return(VectInt.begin()); 
    }
     
    vInt::iterator vInt::end() //
    {
    	return(VectInt.end());
    }
     
    vInt::const_iterator vInt::end() const //
    {
    	return(VectInt.end());
    }
     
    void vInt::affiche() // affichage des vInt sur les consôles (pour le débogage)
    {
    	for(vInt::iterator p = VectInt.begin(), end=VectInt.end(); p!= end;++p)
    	{
    		if((*p)>0)
    		{
    			cout << "+" << *p << ' ';
    		}
    		else
    		{
    			cout << *p << ' ';
    		}
    	}
    }
     
    int vInt::Max() // renvoie le int le plus haut d'un vInt
    {
    	int max;
    	vInt::iterator p=VectInt.begin(), end=VectInt.end();
    	max=(*p);
     
    	for(;p!=end;++p)
    	{
    		if(max<(*p))
    		{
    			max=(*p);
    		}
    	}
    	return max;
    }
     
    vInt& vInt::operator*=(int val) //
    {
    	for(vInt::iterator p = VectInt.begin(), end=VectInt.end(); p!=end ;++p)
    	{
    		*p=(*p)*val;
    	}
    	return *this;
    }
     
    vInt& vInt::operator+=(vInt &vct) //
    {
    	vInt::iterator p = VectInt.begin(), end=VectInt.end();
    	vInt::iterator q = vct.begin(), endc = vct.end();
     
    	while( p != end && q != endc)
    	{
    		*p+=*q;
    		p++;
    		q++;
    	}
    	return *this;
    }
     
    	vInt& vInt::operator=(vInt &vct) //
    {
    VectInt.clear();
    	vInt::iterator q = vct.begin(), endc=vct.end();
     
    	while(q != endc)
    	{
    		VectInt.push_back(*q);
    		q++;
    	}
    	return *this;
    }
     
     
    vInt& vInt::operator-=(vInt &vct) //
    {
    	vInt::iterator p = VectInt.begin(), end=VectInt.end();
    	vInt::iterator q = vct.begin(), endc=vct.end();
     
    	while( p != end && q != endc)
    	{
    		*p-=*q;
    		p++;
    		q++;
    	}
    	return *this;
    }
     
    	vInt& vInt::operator=(int val) //
    {
    for(vInt::iterator p = VectInt.begin(), end= VectInt.end(); p!=end;++p)
    	{
    		*p=val;
    	}
    	return *this;
    }
     
    int& vInt::operator[](unsigned int n) //
    {
    return(VectInt.operator [](n));
    }
     
    unsigned int vInt::size() //
    {
    	return(VectInt.size());
    }

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

Discussions similaires

  1. Iteration VS recursivité
    Par yacinechaouche dans le forum C
    Réponses: 40
    Dernier message: 16/11/2012, 11h52
  2. [struts][iterate] problème logic:iterate avec un Vector
    Par jaimepasteevy dans le forum Struts 1
    Réponses: 9
    Dernier message: 31/03/2004, 18h05
  3. [Struts] logic:iterate avec un Vector
    Par laurentb dans le forum Struts 1
    Réponses: 18
    Dernier message: 03/03/2004, 14h42
  4. [débutant][struts] iterate imbriquée
    Par muim dans le forum Struts 1
    Réponses: 6
    Dernier message: 19/02/2004, 15h13
  5. [debutant]iterator
    Par Wis dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 05/05/2003, 10h49

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