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 :

Comment bien faire son constructeur et surcharge de =


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut Comment bien faire son constructeur et surcharge de =
    Bonjour, pour m'entrainer avec les pointeurs et classes j'ai fait une classe liste, tout fonctionne très bien jusqu'à la destruction de l'objet liste qui contient un pointeur vers la tête de ma liste. Ce qui me conduis à penser que mon constructeur par recopie et la surcharge de l'opérateur = sont fausse.
    voici ce que j'ai fais : le problème est que ca ne marche trop (la surcharge de l'opérateur + contient la même opération, au début je voulais utiliser memcpy mais je ne sais pas trop comment fonctionne la fonction avec ma liste.)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Liste::Liste (const Liste &l)
    {
    //avec memcpy : memcpy(this->tete, l.tete, sizeof(Liste))
    //avec un parcours manuel, la classe IteratorR permet le déplacement dans la liste chaque élément de la liste l est copié dans la liste de l'objet pointé par this
    	for(IteratorR i(l); i.hasNext(); i.getNext())
    		this->AjoutEnTete(i.getCurrent());
    }
    Voici le contenu de la messagebox que m'affiche visual C++
    Exception non gérée à 0x00413fa6 dans Liste.exe*: 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0xcccccccc.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Je crois que c'est un problème d'allocation mémoire.

    Ou alors, je viens peut être de tilter ... comme vous êtes dans le constructeur ( par recopie certes ) de la Liste, celle ci ne peux pas faire d'appel à this ( car l'objet n'est pas encore entièrement construit ).

    Donc va falloir se pencher sur le memcpy() je crois
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    screetch
    Invité(e)
    Par défaut
    ca ressemble a quoi le destructeur de ta liste ?

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Déjà, oublie memcpy, c'est une mauvaise idée pour copier des objets.

    Ensuite, tu ne nous en donne pas assez pour comprendre où est l'erreur. Que fait AjouteEnTete, que fait GetCurrent ? Est-ce que ces fonctions travaillent avec les données contenues dans la liste, ou bien avec les pointeurs qui te permettent d'en assurer l'infrastructure ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    le destructeur est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Liste::~Liste()
    {
    	IteratorRW it (*this);
     
    	while (it.hasNext())
    	{
    		it.suppr();
    	}
    }
    ici mon iteratorrw permet de parcourir la liste, la méthode suppr supprime l'élément courant.

    getCurrent() retourne l'entier contenue dans le maillon de la liste, AjoutEnTete comme son nom le dit ajoute en tete de liste une valeur de type int

  6. #6
    screetch
    Invité(e)
    Par défaut
    est ce que suppr appelle delete sur les objets pointés ?

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    oui dans suppr j'appel delete

  8. #8
    screetch
    Invité(e)
    Par défaut
    a chaque new doit correspondre exactement un seul delete (ni 0 ni 2)
    a vue de nez, lorsque tu copies la liste, les deux listes vont toute les deux appeler "delete" et c'est sans doute ce qui cause ton problème.

    dans l'ordre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    liste.ajoute(new int(5)); // un new
    Liste liste2 = liste;
    // lorsque liste va etre detruite elle va appeler delete
    // lorsque liste2 va etre detruite elle va AUSSI appeler delete

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    c'est aussi ce que je pense mais lorsque j'ajoute une valeur je ne fais pas
    liste.ajoute(new int(5));
    mais
    liste.ajoute(5);

  10. #10
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Comme tu ne nous donnes définitivement pas le code complet, je te conseillerais de reprendre tout "depuis le début", à commencer par "ce qu'il faut pour créer une liste".

    En effet, il y a trois données à prendre en compte pour créer une liste:
    • La donnée que tu veux pouvoir maintenir sous la forme de liste
    • L'élément de la liste, qui maintient la donnée et une référence vers... l'élément suivant (et qui maintient, éventuellement, une référence vers l'élément précédent si tu crées une liste doublement chainée)
    • La liste en elle-même, qui maintiendra, selon la philosophie envisagée, une référence sur le premier élément de la liste, et, éventuellement, une référence sur le dernier élément de la liste (pour permettre l'ajout en fin de liste en "temps constant").
    NOTA:Quand je parle ici de référence, c'est au sens habituelle (non "C++") du terme, car ce sont en réalité des pointeurs, de manière à te permettre de prendre la responsabilité de choisir le moment où les différentes données seront détruites.

    La donnée que tu souhaite maintenir sous forme de liste n'a, en définitive, pas énormément d'importance, parce que ta liste fonctionnera exactement de la même manière si elle maintient des objet de type "char" que si elle maintient des objet d'un type personnalisé particulièrement complexe.

    Nous considérerons ici que l'objet géré par la liste est du type... Type

    Sans même réfléchir aux différentes fonctions qui seront intéressantes pour les éléments de la liste et pour la liste elle-même, on peut déjà estimer que nous aurons des structures proches de
    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
    class ElementList
    {
        /* par facilité, déclarons la liste amie de la classe ElementList */
        friend class List;
        private:
            Type value;
            ElementList * next_;
            /* éventuellement */
            ElementList * previous_;
    };
    class List
    {
        private:
            ElementList * first_;
            /* éventuellement */
            ElementList * last_;
            /* et, éventuellement, pour pouvoir savoir le nombre
             * d'éléments contenus dans la liste en temps constant 
             */
           size_t size_;
    };
    Coplien nous dit que tout objet doit disposer de quatre comportements:
    1. celui qui permet de le créer
    2. celui qui permet de le copier
    3. celui qui permet de l'assigner
    4. celui qui permet de le détruire
    C++ nous indique qu'il fournit ces quatre une implémentation "par défaut" de ces quatre comportements, mais, étant donné que nous venons de décider de baser notre travail sur la gestion dynamique de la mémoire et de mettre les différents éléments de la liste en relation entre eux sous la forme de pointeurs, nous devons prendre les précautions nécessaires en vue d'éviter qu'un élément de la liste ne soit... partagé par plusieurs liste.

    Nous devons donc redéfinir nous même les différents comportements, ce qui nous amène, avec la restriction sur le fait que le type Type doit être lui-même copiable, à un code proche de:
    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
    class ElementList
    {
        /* par facilité, déclarons la liste amie de la classe ElementList */
        friend class List;
        public:
            /* construction */
            ElementList(Type const & t):value_(t),next_(NULL)
            /* éventuellement , previous_(NULL) */
            {
            }
            /* copie */
            ElementList(ElementList const & rhs):value_(rhs.value_),next_(NULL)
            /* éventuellement , previous_(NULL) */
            {
            }
            /* assignation */
            ElementList & operator=(ElementList const & rhs)
            {
                /* comme nous voulons que l'opérateur = nous fournisse une copie
                 * de l'élément qui arrive après, nous utilisons l'idiome copy and
                 * swap
                 */
                ElementList temp(rhs); // appelle le constructeur par copie
                std::swap(value_,temp.value_); /* interverti les valeurs*/
                std::swap(next_,temp.next_); /* interverti les références vers
                                              * l'élément suivant
                                              */
               /* éventuellement
               std::swap(previous_, temp.previous_); /* interverti les références
                                                      * vers l'élément précédent
                                                      */
               return *this;
            }
            /* destruction */
            ~ElementList()
            {
                /* il n'y a pas de gestion dynamique de la mémoire dans ElementList
                 * Le destructeur n'a donc rien à faire
                 *
                 * (nous aurions même pu garder son comportement par défaut)
                 */
            }
        private:
            Type value_;
            ElementList * next_;
            /* éventuellement
             ElementList * previous_;
    };
    class List
    {
        public:
            /* construction (d'une liste vide) */
            Liste():first_(NULL), /*éventuellement , last_(NULL), size_(0) */
            {
            }
            /* copie */
            List(List const & rhs)
            {
                /* la copie devra insérer une copie de chaque élément de la liste
                 * d'origine
                 */
                for(ElementList * it=rhs->first_;it!=rhs->last_;++i)
                    push_back((*it));
            }
            /* affectation */
            List & operator = (List const & rhs)
            {
                /* lorsque l'on affecte une liste à une liste autre, il faut:
                 * - affecter une copie de la liste de "destination" à la liste
                 *   "source"
                 * - veiller à ce que le contenu d'origine de la liste soit 
                 *   correctement détruit
                 * 
                 * l'idiome copy and swap nous y aide :D
                 */
                List temp(rhs);
                std::swap(first_,temp.first_);
                /* éventuellement
                   std::swap(last_,temp.last_);
                   std::swap(size_,temp.last_);
                 */
               return *this;
            }
            /* destruction */
            ~List()
            {
                /* lorsqu'une liste est détruite, il faut veiller à détruire l'ensemble
                 * de ses éléments
                 */
               ElementList* temp;
               while(first_)
               {
                   temp= first_->next;
                   delete first_;
                   first = temp;
               }
               last_=NULL;
               size=0;
            }
     
        private:
            ElementList * first_;
            /* éventuellement */
            ElementList * last_;
            /* et, éventuellement, pour pouvoir savoir le nombre
             * d'éléments contenus dans la liste en temps constant 
             */
           size_t size_;
    };
    En lisant ce code, tu aura remarqué que j'ai utilisé:
    • ++it (alors que it est un ElementList* )
    • (*it) (alors que it est un ElementList *)
    • push_back( appliqué à une Liste)
    Les deux premières instructions mettent en valeur le fait est que ElementList a sémantique d'itérateur, et que, dans notre cas, un itérateur doit fournir certains comportements qui s'avéreront des plus intéressants:
    • Pouvoir utiliser une syntaxe simple, presque "arithmétique", pour accéder à l'élément suivant
    • pouvoir accéder à son contenu comme s'il s'agissait d'un pointeur

    Nous allons donc "compléter" notre classe ElementList ci-dessus avec au minimum deux fonctions membres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class ElementList
    {
        /* je ne réécris pas tout ;) */
        public:
            Type & operator *(){return value_;}
            /* la version "constante" */
            Type const & orperator *() const{return value_;}
            /* accéder à l'élément suivant */
            ElementList * operator++(){return next_;}
            /* et sa version constante */
            ElementList const * oeprator ++() const{return next_;}
    };
    La dernière met en lumière le fait que, si l'on dispose d'une liste, le comportement minimum que l'on attend d'elle est de pouvoir... ajouter un nouvel objet en fin de liste.

    Nous allons donc "compléter" notre classe List avec
    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
    class List
    {
        /* je ne réécris pas tout */
        public:
            void push_back(Type const & toadd)
            {
                /* créons l'élément */
                ElementList * temp=new ElementList(toadd);
                /* si nous avons déjà un dernier élément, le nouvel élément
                 * suit ce  dernier élément 
                 */
                if(last_) 
                    last_->next = temp;
               /* et le nouvel élément devient le dernier */
               last_=temp;
               /* si nous n'avons pas de premier élément dans la liste
                * le nouvel élément devient... le premier de la liste
                */
               if(!first)
                   first=temp;
               /* et nous mettons la taille à jour, 
                * si on dispose de l'information 
                */
               ++size_;
            }
    };
    Une fois que tu as cette base, tu peux envisager de rajouter un tas de comportements, pour autant qu'ils soient adaptés et cohérents à tes différents objets, et tu auras la certitude que, quoi que tu fasse avec ta liste, tu n'enverra pas le programme "cueillir les marguerites"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par amateurc Voir le message
    c'est aussi ce que je pense mais lorsque j'ajoute une valeur je ne fais pas
    liste.ajoute(new int(5));
    mais
    liste.ajoute(5);
    comme je te l'ai dit, a chaque new doit correspondre exactement un delete
    ou est ton new ? ou est ton delete ?

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    Excuser-moi, en effet vous ne pouvez pas m'aider efficacement si je ne montre pas le code donc le voici, le Liste.cpp contient les méthodes de liste, Liste.h contient des classes implémentées inline et la déclaration de la classe Liste, et 2 jeux d'essai avec main.cpp.

    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
    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
     
    #ifndef __LISTE__
    #define __LISTE__
     
    #include <iostream>
     
    /*la classe Noeud contient la valeur stocké dans la liste et le pointeur vers l'element suivant*/
    class Noeud
    {
    	/*pour utiliser dans la classe Iterator la classe noeud sans passer par les getteurs et setteurs*/
    	friend class Iterator;
     
    	private:
    		int val;
    		Noeud *suivant;
     
    	public:
    		Noeud(const Noeud &n)
    		{
    			Noeud no(n);
     
    			std::swap(this->val, no.val);
    			std::swap(this->suivant, no.suivant);
    		}
     
    		Noeud(int val, Noeud *n = NULL) : val(val), suivant(n)
    		{
    		}
     
    		int getVal()const
    		{
    			return this->val;
    		}
     
    		Noeud* getSuivant()const
    		{
    			return this->suivant;
    		}
     
    		void setVal(const int &val)
    		{
    			this->val = val;
    		}
     
    		void setSuivant(Noeud *n)
    		{
    			this->suivant = n;
    		}
     
    		Noeud& operator=(const Noeud &n)
    		{
    			Noeud tmp = n;
     
    			std::swap(this->val, tmp.val);
    			std::swap(this->suivant, tmp.suivant);
     
    			return *this;
    		}
    };
     
    /*classe qui contient un élément de tete et quelques fonctions sur les listes comme l'empilage et le depilage*/
    /*ici les méthodes n'ont pas a etre inline*/
    class Liste
    {
    	/*idem que la classe Noeud*/
    	friend class Iterator;
     
    	private:
    		Noeud *tete;
     
    	public:
    		Liste();
    		Liste(const Liste &l);
    		~Liste();
     
    		void Empiler(int val);
    		int Depiler();
     
    		friend std::ostream& operator<<(std::ostream &o, const Liste &l);
    		Liste& operator=(const Liste &l);
    };
     
    /*classe qui permet de se déplacer librement dans la liste sans avoir a toucher à la tete de liste de la classe Liste*/
    class Iterator
    {	
    	protected:
    		Noeud **courant;
     
    	public:
    		Iterator(){}
     
    		Iterator(const Iterator &i) : courant(i.courant)
    		{
    		}
     
    		Iterator(const Liste &l)
    		{
    			Liste *laux = const_cast<Liste*> (&l);
    			this->courant = &(laux->tete);
    		}
     
    		/*verifie que l'element suivant existe : si le pointeur courant == null => pas d'element suivant*/
    		bool hasNext()const
    		{
    			return ((*courant) == NULL) ? false : true;
    		}
     
    		/*obtenir l'element suivant*/
    		void getNext()
    		{
    			courant = &((*courant)->suivant);
    		}
     
    		/*retourne l'entier stocke dans le noeud courant de la liste*/
    		int getCurrent()const
    		{
    			return (*courant)->getVal();
    		}
     
    		/*incrementation => raccourcis de getNext()*/
    		Iterator& operator++()
    		{
    			this->getNext();
    			return *this;
    		}
    };
     
    /*classe qui permet de faire des modifications sur la liste a partir d'un iterateur*/
    class IteratorW : public Iterator
    {
    	public:
    		IteratorW(const IteratorW &i) : Iterator(i)
    		{
    		}
     
    		IteratorW(const Liste &l) : Iterator(l)
    		{
    		}
     
    		void Inserer(int val)
    		{
    			*courant = new Noeud(val, (*courant));
    		}
     
    		void Supprimer()
    		{
    			Noeud *aux = *courant;
    			*courant = (*courant)->getSuivant();
    			delete aux;
    		}
    };
     
    #endif
    Liste.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
     
    #include "Liste.h"
     
     
    Liste::Liste()
    {
    	this->tete = NULL;
    }
     
    Liste::Liste(const Liste &l) : tete(l.tete)
    {
    	/*for(Iterator it(l); it.hasNext(); ++it)
    		this->Empiler(it.getCurrent());*/
    }
     
    Liste::~Liste()
    {
    	std::cout << "DEBUT DE DESTRUCTION DE L'OBJET" << std::endl;
    	IteratorW it(*this);
     
    	while(it.hasNext())
    		it.Supprimer();
     
    	std::cout << "FIN DE DESTRUCTION DE L'OBJET" << std::endl;
    }
     
    void Liste::Empiler(int val)
    {
    	this->tete = new Noeud(val, this->tete);
    }
     
    int Liste::Depiler()
    {
    	IteratorW it(*this);
     
    	int val = it.getCurrent();
    	it.Supprimer();
     
    	return val;
    }
     
    std::ostream& operator<<(std::ostream &o, const Liste &l)
    {
    	for(Iterator it(l); it.hasNext(); it.getNext())
    		o << it.getCurrent() << " ";
     
    	return o;
    }
     
    Liste& Liste::operator=(const Liste &l)
    {
    	Liste tmp = l;
     
    	std::swap(tete, tmp.tete);
     
    	return *this;
    }
    main.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
     
    #include <iostream>
    #include "Liste.h"
     
    using namespace std;
     
    int main()
    {
    	Liste l;
     
    	for(int i = 0; i < 15; i++)
    		l.Empiler(i);
     
    	for(Iterator it(l); it.hasNext(); it.getNext())
    		cout << it.getCurrent() << " ";
     
    	cout << endl << l << endl;
     
    	Liste l2(l);
     
    	cout << l2 << endl;
     
    	system("pause > nul");
    	return EXIT_SUCCESS;
    }
    je mets aussi un aperçu du résultat :
    14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    DEBUT DE DESTRUCTION DE L'OBJET
    FIN DE DESTRUCTION DE L'OBJET
    DEBUT DE DESTRUCTION DE L'OBJET
    le 2eme jeu :
    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
    #include <iostream>
    #include "Liste.h"
     
    using namespace std;
     
    int main()
    {
    	Liste l;
     
    	for(int i = 0; i < 15; i++)
    		l.Empiler(i);
     
    	cout << endl << l << endl;
     
    	Liste l2 = l;
     
    	cout << l2 << endl << l << endl;
     
    	cout << l2.Depiler() << endl << l2 << endl << l << endl;
     
    	system("pause > nul");
    	return EXIT_SUCCESS;
    }
    et le resultat :
    14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    14
    13 12 11 10 9 8 7 6 5 4 3 2 1 0
    -17891602

  13. #13
    screetch
    Invité(e)
    Par défaut
    argh ma faute, la réponse etait deja dans le premier message

    il y a plusieurs erreurs mais dans le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Liste::Liste (const Liste &l)
    {
    //avec memcpy : memcpy(this->tete, l.tete, sizeof(Liste))
    //avec un parcours manuel, la classe IteratorR permet le déplacement dans la liste chaque élément de la liste l est copié dans la liste de l'objet pointé par this
    	for(IteratorR i(l); i.hasNext(); i.getNext())
    		this->AjoutEnTete(i.getCurrent());
    }
    ici, tete n'est pas initialisée, il recoit la valeur par défaut de debug qui est de pointer sur 0xCCCCCCCC. cette valeur un peu spéciale va certainement faire crasher le programme dés que cette valeur sera accédée (car il n'y a pas souvent quelque chose a 0xCCCCCCCC).
    dans le constructeur ensuite, tu empiles des trucs et va utiliser tete qui n'a jamais été initialisé => kaboom

    ca c'est pour l'erreur originale

    une erreur de logique : dans ce constructeur de copie, tu ajoutes en tete la queue de la liste, tu vas donc la renverser

    unee erreur que tu as déjà corrigée il me semble dans le destructeur de Liste : tu ne supprimais qu'un élément sur deux

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    fichu initialisation du pointeur de tete. En effet il fallait lui mettre NULL.
    Merci de l'aide, j'en ai profité pour créer la liste dans le bonne ordre.
    Merci de vos aides.

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

Discussions similaires

  1. Comment bien déboguer son code ?
    Par D[r]eadLock dans le forum Débuter
    Réponses: 47
    Dernier message: 02/04/2024, 16h06
  2. Class de mesh, comment bien faire ?
    Par Tosh dans le forum Développement 2D, 3D et Jeux
    Réponses: 8
    Dernier message: 24/04/2007, 12h24
  3. [MS/SQL 2K][Securité][Restauration]Comment bien faire ?
    Par jbat dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 18/04/2007, 11h18
  4. [VBA][Excel] Comment bien structurer son code?
    Par skystef dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 15/03/2007, 19h39
  5. Réponses: 1
    Dernier message: 05/09/2006, 17h20

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