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 :

Problème listes chainées


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Points : 5
    Points
    5
    Par défaut Problème listes chainées
    Bonjour à tous !

    J'ai un petit travail à faire pour manipuler des listes chainées. Pour ce faire, je dispose de 2 classes, et j'ai obligation de redéfinir les opérateurs pour effectuer mes opérations.
    Je suis deja bloqué sur mon premier opérateur que je teste : l'opérateur + qui est en fait la "concaténation" de 2 listes.

    Lorsque je le teste, avec mes listes l1 et l2, l1 contenant 0 et l2 contenant 1, il devrait m'afficher 0 1 , or il ne m'affiche que 0 ! On dirait bien qu'il y a un problème que je ne parviens pas à identifier.

    Voici mon code :

    Fichier liste.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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    // Creer une liste d'objets de la classe T en completant
    // l'interface suivante. Transformer ensuite la liste en
    // liste generique (template)
    //
     
    // Classe maillon
    class maillon {
          // Champs prives
          private:
            double data;
            maillon *suivant;
     
          // Forme canonique de Coplien
          public:
            maillon();
            maillon(const maillon&);
            maillon(double);
            ~maillon();
            maillon& operator=(const maillon&);
     
          // Autres methodes et operateurs
          // ...
          friend class liste;
    };
     
    // Classe liste
    class liste {
          // Champs prives
          private:
            maillon *tete, *fin, *cour;
     
          // Forme canonique de Coplien
          public:
            liste();
            liste(const liste&);
            liste(const maillon&);
            ~liste();
            liste& operator=(const liste&);
     
          // Ajout de maillons
             liste& operator+ (double);
             liste& operator+ (const maillon&);
             liste& operator+ (const liste&);
     
          // Suppression de maillons
             liste& operator- (double); // suppression de la premiere occurence de T
             liste& operator- (int); // suppression du maillon d'indice donne
     
             void supprime_tete(); // supprime la tete de la liste
             void supprime(); // supprime tous les elements de la liste
     
          // Suppression 
     
          // Entrees-sorties
             void affiche () const; // Fonction constante qui ne peut pas modifier les champs de la classe
     
          // Autres methodes et operateurs
          friend class maillon;
    };

    Fichier liste.cc :
    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
     
    #include "liste.h"
    #include <iostream>
     
    //constructeur par défaut de maillon
    maillon::maillon() {
      data = 0.0;
      suivant = NULL;
    }
     
    //constructeur par recopie de maillon
    maillon::maillon(const maillon& m) {
      data = m.data;
      suivant = m.suivant;
    }
     
    //constructeur avec une valeur passée en paramètre
    maillon::maillon(double val) {
      data = val;
      suivant = NULL;
    }
     
    //destructeur de maillon
    maillon::~maillon() {
      if(suivant) delete suivant;
    }
     
    //redéfinition de l'opérateur = pour les maillons
    maillon& maillon::operator=(const maillon& m) {
      data = m.data;
      suivant = m.suivant;
      return (*this);
    }
     
     
    //-----------------------------------------------------------------------
     
     
    //constructeur par défaut de la classe liste
    liste::liste() {
      tete = NULL;
      fin = NULL;
      cour = NULL;
    }
     
    //constructeur par recopie de la classe liste
    liste::liste(const liste& l) {
      tete = NULL;
      fin = NULL;
      cour = NULL;
      *this+l;
    }
     
    //constructeur prenant un maillon en paramètre
    liste::liste(const maillon& m) {
      tete = new maillon(m);
      fin = new maillon(m);
      cour = new maillon(m);
    }
     
    //destructeur de la classe liste
    liste::~liste() {
      supprime();
    }
     
    //Redéfinition de l'opérateur = pour les listes
    liste& liste::operator=(const liste& l) {
      supprime();
      return *this+l;
    }
     
    //Redéfinition de l'opérateur + pour les listes :
    //Création puis ajout d'un maillon en fin de liste
    liste& liste::operator+(double val) {
      maillon c;
      c.data = val;
      fin->suivant = new maillon(c);
    }
     
    //Redéfinition de l'opérateur + pour les listes :
    //Ajout d'un maillon en fin de liste
    liste& liste::operator+(const maillon& m) {
      fin->suivant=new maillon(m);
    }
     
    //Redéfinition de l'opérateur + pour les listes :
    //concaténation de deux listes
    liste& liste::operator+(const liste& l) {
      maillon *c = l.tete;
      while(c) {
        if(tete == NULL) tete=fin=cour=new maillon(*c);
        else {
          fin->suivant = new maillon(*c);
          fin = fin->suivant;
        }
        fin->suivant = NULL;
        c = c->suivant;
      }
      return *this;
    }
     
    //Méthode supprime de la classe liste :
    void liste::supprime() {
      while(tete) {
        cour=tete->suivant;
        delete tete;
        tete=cour;
      }
    }
     
     
    void liste::affiche() const {
      maillon *c = tete;
      while(c != NULL) {
        std::cout << c->data << std::endl;
        c = c->suivant;
      }
    }
     
     
     
    //http://www.seasofcheese.net/~julien/enseignement/cplusplus/tp/tp2_corrige/
     
     
     
     
    //méthode main pour tester le programme
    int main(int argc, char **argv)
     
    {
     
     
     
    	std::cout << "PROGRAMME DE TEST" << std::endl;
     
     
     
    	maillon m(0.0), m1(1.0),m2(2.0),m3(3.0),m4(4.0),m5(5.0);
            liste l(m);
            liste l2(m1);
            liste l3=l+l2;
     
            l3.affiche();
     
     
     
    	std::cout << "SORTIE TEST" << std::endl;
     
    }


    Voici l'affichage :

    PROGRAMME DE TEST
    0
    SORTIE TEST




    Merci à vous !

  2. #2
    screetch
    Invité(e)
    Par défaut
    tu as deja de la chance que ca ne te plante pas a la tete je crois.

    tes constructeurs par copie et operateur = ne font qu'affecter le pointeur vers un autre maillon. on peut donc avoir deux maillons qui pointent vers le meme suivant (l'original, et sa copie)
    lorsque les maillons sont detruits, ils vont detruire le suivant. Ceux qui ont été copiés vont detruire deux fois leur suivant, puisque maintenant ils le partagent.

    Pour remédier a ca, un maillon doit faire une copie "profonde" de l'objet, c'est a dire dupliquer non pas le pointeur mais carrément ce qui est pointé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //constructeur par recopie de maillon
    maillon::maillon(const maillon& m) {
      data = m.data;
      if(m.suivant)
      {
        suivant = new maillon(*m.suivant);
      }
    }
    de meme pour operator=

  3. #3
    screetch
    Invité(e)
    Par défaut
    et sinon pour ton erreur, c'est du a la facon dont tucrée ta liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     //constructeur prenant un maillon en paramètre
    liste::liste(const maillon& m) {
      tete = new maillon(m);
      fin = tete;
      cour = tete;
    }
    sinon, la tete, la queue et tout ne sont pas connectés, ce qui la fout mal.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Points : 5
    Points
    5
    Par défaut
    Merci beaucoup ça marche enfin !

    Par contre petit souci sur mon opérateur+, lorsque je fais l3 = l+l2, ça fonctionne mais la liste l est également modifiée par le résultat et je ne sais pas trop si c'est ce que l'on veut...
    Fin d'un sens si c'est une concaténation au sens pure oui c'est logique.



    Autrement j'ai des soucis aussi avec ces 2 opérator + qui fonctionnent, mais ils doivent être buggés car quand j'ajoute autre chose après, le truc que j'avais ajouté avant a été effacé, exemple
    liste l(0.0)
    l+2 m'affiche bien 0 2
    l+3 ne m'affiche pas 0 2 3 mais 0 3 !

    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
     
    //Redéfinition de l'opérateur + pour les listes :
    //Création puis ajout d'un maillon en fin de liste
    liste& liste::operator+(double val) {
      maillon c;
      c.data = val;
      c.suivant = NULL;
      fin->suivant = new maillon(c);
    }
     
    //Redéfinition de l'opérateur + pour les listes :
    //Ajout d'un maillon en fin de liste
    liste& liste::operator+(const maillon& m) {
      fin->suivant=new maillon(m);
    }



    EDIT : J'ai rien dit ! En fait je commence tout de même à comprendre un certain nombre de trucs et j'ai réussi à corriger ce problème ! Par contre je vais faire d'autres trucs et à mon avis je vais rencontrer aussi des problèmes et en plus après faut que je refasse le tout avec des templates ! Donc gardez ce topic sous la main, je risque d'y reposter !

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Points : 5
    Points
    5
    Par défaut
    J'ai un problème avec mon constructeur par défaut de ma classe liste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //constructeur par défaut de la classe liste
    liste::liste() {
      tete = NULL;
      fin = tete;
      cour = tete;
    }
    Après quand je veux faire des opérations dessus genre créer une liste, puis utiliser l'opérateur + il me dit que ma liste n'est pas de type liste

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    Vu ta dernière edit, il va falloir poster plus de code.
    Notamment, montrer ton fameux nouvel opérateur +/+=.

  7. #7
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Attention, il ne faut pas mélanger l'opérateur + et += !

    L'opérateur + ne devrait jamais renvoyer une référence vers *this.

    D'une manière générale, l'opérateur+ doit être constant.
    En réalité, l'opérateur + doit toujours renvoyer un temporaire (constant, pour la sémantique) qui représente l'union des 2 opérandes.

    C'est l'opérateur += qui doit renvoyer une référence vers *this et effectivement ajouter l'opérande de droite à l'objet courant.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Et en général l'op+ est libre et exprimé en terme de +=

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Points : 5
    Points
    5
    Par défaut
    Voila mon nouvel opérateur + (il s'agit bien la d'une concaténation qui modifie ma liste courante) :

    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
     
    //Redéfinition de l'opérateur + pour les listes :
    //concaténation de deux listes
    liste& liste::operator+(const liste& l) {
      maillon *c = l.tete;
      while(c) {
        if(tete == NULL) tete=fin=cour=new maillon(*c);
        else {
          fin->suivant = new maillon(*c);
          fin = fin->suivant;
        }
        fin->suivant = NULL;
        c = c->suivant;
      }
      return *this;
    }
    Et j'ai tout simplement dans mon main :
    liste l0();
    l0+l;//l étant deja instanciée avant...
    l0.affiche();



    Autre chose, j'ai également eu énormément de problème pour une fonction qui ne marche toujours pas (boucle infinie à l'affichage oblige), la ligne incriminée est en rouge :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //Insertion d'un maillon à la nième position :
    void liste::insert(const maillon& m, int n) {
      cour = tete;
      for(int i=1;i<n;i++) {
        cour = cour->suivant;
      }
      cour->suivant = cour;
      cour = new maillon(m);
    }

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    On dirait que tu as la tête dure...

    SI ÇA MODIFIE LA LISTE COURANTE, ÇA N'EST PAS UN OPÉRATEUR + !!!

    La moindre des choses que tu puisses faire est renommer ça en operator+=.

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Points : 5
    Points
    5
    Par défaut
    Mon prof a pourtant été très clair...
    La sémantique des opérateurs n'implique pas forcément un cas d'utilisation précis. On peut très bien dire ici que mon opérateur + fonctionne comme ça, je ne vais pas aller contre mon prof non plus
    Cela ne résout pas mon problème de constructeur par défaut qui ne fonctionne pas ? A moins que l'erreur vienne de là mais j'en doute, auquel cas j'aurais vraiment rien compris !

    Par contre médinoc, as-tu vu mon édition ?

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    Ben si, tu vas remonter les bretelles à ton prof, et lui rappeler la différence entre + et +=.
    Mon prof aussi a fait la même connerie, et il n'a échappé à la correction que parce que je n'ai compris qu'après la fin de l'année scolaire.

    Et pour ton insertion:
    Code C++ : 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
    //Insertion d'un maillon à l'index n
    //0 pour insérer en tête, et ainsi de suite.
    void liste::insert(const maillon& m, size_t n) {
    	maillon* pInsereAvant = tete;
    	maillon** ppInsereAvant = &tete;
     
    	for(int i=0 ; i<n ; i++) {
    		ppInsereAvant = &pInsereAvant->suivant;
    		pInsereAvant = pInsereAvant->suivant;
    	}
    	assert(*ppInsereAvant == pInsereAvant);
     
    	maillon *pNouveau = new maillon(m);
    	pNouveau->suivant = pInsereAvant;
    	*ppInsereAvant = pNouveau;
    }

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Points : 5
    Points
    5
    Par défaut
    Houla je ne comprends pas tout ton code ! un pointeur de pointeur ?? et c'est quoi assert ?

    Et comment je fais pour mon constructeur par défaut ?

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    Bonjour,
    1. Il faut un pointeur de pointeur, pour modifier ce qui pointe sur le maillon avant lequel insérer.
      • Si on insère en tête de liste, c'est le pointeur de tête qu'il faut modifier, donc on pointe dessus.
      • Sinon, c'est le pointeur d'un élément vers l'autre qu'il faut modifier, donc on pointe dessus.
    2. assert, c'est une fonction pour vérifier un truc censé être toujours vrai. Si c'est faux, ça plante. Ici, on utilise cette fonction pour vérifier qu'on pointe bien sur le pointeur à modifier. Si l'assertion foire, c'est que j'ai fait une connerie en écrivant le code.
    3. Peux-tu rappeler le problème à propos du constructeur par défaut? Je ne me souviens pas de celui-là et j'ai la flemme de chercher.

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Points : 5
    Points
    5
    Par défaut
    Je vais pêter un câble, je suis toujours là dessus et pas grand chose ne marche !

    Bon passons, le but de l'exercice était donc de passer aux templates, ce que j'ai fais, et là patatrac ! me voila avec plus de 100 erreurs. Après des heures de boulot, je n'ai plus que ces lignes là d'erreur :

    liste.h: In instantiation of ‘maillon<T>’:
    liste.cc:5: instantiated from here
    liste.h:15: erreur: template argument required for ‘struct liste’
    liste.cc:5: erreur: trop peu de patron de listes de paramètres
    liste.cc:11: erreur: trop peu de patron de listes de paramètres
    make: *** [liste.o] Erreur 1


    Pouvez vous m'aider ? Je dois avoir finit ça très rapidement malheuresement...

    Voici le code :
    fichier liste.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
    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
     
    // Creer une liste d'objets de la classe T en completant
    // l'interface suivante. Transformer ensuite la liste en
    // liste generique (template)
    //
     
     
    class T {
    };
     
    // Classe maillon
    template <class T> class maillon {
          // Champs prives
          private:
            T data;
            maillon<T> *suivant;
     
          // Forme canonique de Coplien
          public:
            maillon();
            maillon(const maillon<T>&);
            maillon(T);
            ~maillon();
            maillon<T>& operator=(const maillon<T>&);
     
          // Autres methodes et operateurs
          // ...
          friend class liste;
    };
     
    // Classe liste
    template <class T> class liste {
          // Champs prives
          private:
            maillon<T> *tete, *fin, *cour;
            int taille;
     
          // Forme canonique de Coplien
          public:
            liste();
            liste(const liste<T>&);
            liste(const maillon<T>&);
            ~liste();
            liste<T>& operator=(const liste<T>&);
     
          // Ajout de maillons
             liste<T>& operator+ (T);
             liste<T>& operator+ (const maillon<T>&);
             liste<T>& operator+ (const liste<T>&);
     
          // Suppression de maillons
             liste<T>& operator- (T); // suppression de la premiere occurence de la valeur passée en paramètre
             liste<T>& operator- (int); // suppression du maillon d'indice donne
     
             void supprime_tete(); // supprime la tete de la liste
             void supprime(); // supprime tous les elements de la liste
     
          // Suppression 
     
          // Entrees-sorties
             void affiche () const; // Fonction constante qui ne peut pas modifier les champs de la classe
     
          // Autres methodes et operateurs
             void insert(const maillon<T>&, int); //Insère le maillon à la position indiquée
          friend class maillon<T>;
    };

    Fichier liste.cc :
    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
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
     
    #include "liste.h"
    #include <iostream>
     
    //constructeur par défaut de maillon
    maillon<T>::maillon() {
      data = T();
      suivant = NULL;
    }
     
    //constructeur par recopie de maillon
    maillon<T>::maillon(const maillon<T>& m) {
      data = m.data;
      if(m.suivant)
      {
        suivant = new maillon(*m.suivant);
      }
    }
     
    //constructeur avec une valeur passée en paramètre
    maillon<T>::maillon(T val) {
      data = val;
      suivant = NULL;
    }
     
    //destructeur de maillon
    maillon<T>::~maillon() {
      if(suivant) delete suivant;
    }
     
    //redéfinition de l'opérateur = pour les maillons
    maillon<T>& maillon<T>::operator=(const maillon<T>& m) {
      data = m.data;
      if(m.suivant)
      {
        suivant = new maillon(*m.suivant);
      }
      return (*this);
    }
     
     
    //-----------------------------------------------------------------------
     
     
    //constructeur par défaut de la classe liste
    liste<T>::liste() {
      tete = NULL;
      fin = tete;
      cour = tete;
      taille = 0;
    }
     
    //constructeur par recopie de la classe liste
    liste<T>::liste(const liste<T>& l) {
      tete = NULL;
      fin = tete;
      cour = tete;
      taille = l.taille;taille = l.taille;
      *this+l;
    }
     
    //constructeur prenant un maillon en paramètre
    liste<T>::liste(const maillon<T>& m) {
      tete = new maillon(m);
      fin = tete;
      cour = tete;
      taille++;
    }
     
    //destructeur de la classe liste
    liste<T>::~liste() {
      supprime();
    }
     
    //Redéfinition de l'opérateur = pour les listes
    liste<T>& liste<T>::operator=(const liste<T>& l) {
      supprime();
      taille = l.taille;
      return *this+l;
    }
     
    //Redéfinition de l'opérateur + pour les listes :
    //Création puis ajout d'un maillon en fin de liste
    liste<T>& liste<T>::operator+(T val) {
      maillon c;
      c.data = val;
      c.suivant = NULL;
      if(tete == NULL) {
        tete = new maillon(c);
        return *this;
      }
      fin->suivant = new maillon(c);
      fin = fin->suivant;
      fin->suivant = NULL;
      taille++;
      return *this;
    }
     
    //Redéfinition de l'opérateur + pour les listes :
    //Ajout d'un maillon en fin de liste
    liste<T>& liste<T>::operator+(const maillon<T>& m) {
      fin->suivant = new maillon(m);
      fin = fin->suivant;
      fin->suivant = NULL;
      taille++;
      return *this;
    }
     
    //Redéfinition de l'opérateur + pour les listes :
    //concaténation de deux listes
    liste<T>& liste<T>::operator+ (const liste<T>& l) {
      maillon<T> *c = l.tete;
      while(c) {
        if(tete == NULL) tete=fin=cour=new maillon(*c);
        else {
          fin->suivant = new maillon(*c);
          fin = fin->suivant;
        }
        fin->suivant = NULL;
        c = c->suivant;
      }
      taille += l.taille;
      return *this;
    }
     
    //Suppression de la premiere occurence de valeur
    liste<T>& liste<T>::operator-(T) {
      //Si le maillon à supprimer est le premier, alors on appelle la méthode que l'on a définie
      if(tete->data == valeur) {
        supprime_tete();
        return *this;
      }
     
      //On fait une première boucle pour trouver le maillon correspondant
      cour = tete;
      while(cour->data != valeur) {
        cour = cour->suivant;
      }
      //On garde une copie de ce maillon
      maillon<T> *c = cour;
      //Seconde boucle pour trouver le maillon précèdent celui que l'on doit supprimer
      cour = tete;
      while(cour->suivant != c) {
        cour = cour->suivant;
      }
      //On peut maintenant dire que le maillon précédent celui que l'on veut supprimer
      //doit pointer vers le suivant, puis on détruit notre maillon
      cour->suivant = c->suivant;
      delete c;
      taille--;
      return *this;
    }
     
    //Suppression du maillon d'indice donné en paramètre
    liste<T>& liste<T>::operator-(int rang) {
      if(rang == 1) {
        supprime_tete();
        return *this;
      }
      maillon<T> *c;
      cour = tete;
      int i=1;
      while(i<rang) {
        c = cour;
        cour = cour->suivant;
        i++;
      }
      c->suivant = cour->suivant;
      delete(cour);
      taille--;
      return *this;
    }
     
    //Supprime la tête de la liste :
    void liste<T>::supprime_tete() {
      cour=tete->suivant;
      tete=cour;
      taille--;
    }
     
    //Méthode supprime de la classe liste :
    void liste<T>::supprime() {
      while(tete) {
        cour=tete->suivant;
        delete tete;
        tete=cour;
      }
      taille=0;
    }
     
    //Affichage d'une liste :
    void liste<T>::affiche() const {
      maillon<T> *c = tete;
      while(c != NULL) {
        std::cout << c->data << " ";
        c = c->suivant;
      }
      std::cout << std::endl;
    }
     
     
     
     
    //méthode main pour tester le programme
    int main(int argc, char **argv)
     
    {
     
     
     
    	std::cout << "PROGRAMME DE TEST" << std::endl;
     
     
    	maillon<double> m(0.0), m1(1.0),m2(2.0),m3(3.0),m4(4.0),m5(5.0);
            std::cout << "Création d'une liste à partir d'un maillon :" << std::endl;
            std::cout << "l: ";
            liste<double> l(m);
            l.affiche();
            std::cout << "Création d'une liste à partir d'une autre liste (recopie) :" << std::endl;
            liste<double> l2(l);
            std::cout << "l2: ";
            l2.affiche();
            std::cout << "Concaténation de 2 listes :" << std::endl;
            std::cout << "l+l2: ";
            l+l2;
            l.affiche();
            std::cout << "Ajout d'un d'un double en fin de liste :" << std::endl;
            std::cout << "l+1.0: ";
            l+1.0;
            l.affiche();
            std::cout << "l+2.0: ";
            l+2.0;
            l.affiche();
            std::cout << "l+3.0: ";
            l+3.0;
            l.affiche();
            std::cout << "Ajout d'un maillon en fin de liste :" << std::endl;
            std::cout << "l+m4(4.0): ";
            l+m4;
            l.affiche();
            std::cout << "l+m5(5.0): ";
            l+m5;
            l.affiche();
            std::cout << "Suppression de la tête :" << std::endl;
            l.supprime_tete();
            l.affiche();
            std::cout << "On retire le deuxième élément de la liste :" << std::endl;
            l-2;
            l.affiche();
     
     
     
    	std::cout << "SORTIE TEST" << std::endl;
     
    }


    D'un autre coté je ne comprends pas le fonctionnement des templates dans une application, et vu que c'est la première...la note va être belle ! Ca m'énerve, mais ça m'énerve....

  16. #16
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Quelques remarques en vrac :

    • Il manque les template <typename T> devant la définition des fonctions templates.
    • La déclaration de class T n'a rien à faire ici.
    • Par contre, il manque la déclaration anticipé de la classe : template <typename T> class liste; avant la définition de la classe maillon.
    • C'est friend class liste<T>; pas friend class liste;
    • La classe maillon n'a pas besoin d'être amie de liste, donc la ligne friend class maillon<T>; n'a aucune raison d'être présente.
    • Dans le constructeur par recopie de maillon, l'élément suivant du dernier maillon n'est pas valorisé et vaut donc n'importe quoi.

  17. #17
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par gl Voir le message
    Quelques remarques en vrac :

    • Il manque les template <typename T> devant la définition des fonctions templates.

    Il faut les mettre où et comment ? dans le .h ou le .cc ?
    Du coup j'ai récupérer mes plus de 100 erreurs...

Discussions similaires

  1. un petit problème : listes chainés
    Par anes-saad dans le forum C
    Réponses: 2
    Dernier message: 07/05/2011, 00h27
  2. Problème Listes chainées Structure contenant
    Par loco_info dans le forum C
    Réponses: 3
    Dernier message: 17/05/2007, 14h08
  3. problème liste chainée
    Par jonjon83 dans le forum C
    Réponses: 11
    Dernier message: 28/02/2007, 19h58
  4. Problème Liste chainée
    Par skyangel dans le forum C++
    Réponses: 16
    Dernier message: 07/06/2006, 14h14

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