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++

Vue hybride

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

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    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
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    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
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    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
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Vu ta dernière edit, il va falloir poster plus de code.
    Notamment, montrer ton fameux nouvel opérateur +/+=.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

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

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