Constructeur de recopie et pointeur sur pointeur

Signaler
Messages postés
24
Date d'inscription
jeudi 6 mai 2004
Statut
Membre
Dernière intervention
21 janvier 2005
-
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
-
Bonjour je bloque sur la définition d'un constructeur de recopie d'une classe "liste" afin de sortir du programme principale sans provoque une exeption ou erreur... :)
Je me doute que cela tourne autour des "news" et "delete" mais je dois mal les utiliser... merci pour une solution et voici le code :

****************************************************

l'entete

//---------------------------------------------------------------------------
#ifndef MULTIPLE
#define MULTIPLE
//---------------------------------------------------------------------------
#include
#include <cstddef>
using namespace std;
//---------------------------------------------------------------------------
/* Définition de la structure element
*/
struct element
{
element *suivant; // un pointeur sur l'élément suivant
void *contenu; // un pointeur de type indéfini sur le contenu
};
/* Définition de la classe liste
*/
class liste
{
element *debut; // le premier élément
element *courant; // l'élément courant (en traitement)
public :
inline liste(); // constructeur
inline ~liste(); // destructeur
//inline liste(const liste &);
void ajoute(void *);
void premier();
void * prochain();
int fini();
};
//---------------------------------------------------------------------------
inline liste :: liste()
{
debut = NULL;
courant = NULL;
}
//---------------------------------------------------------------------------
inline liste :: ~liste()
{
element *suiv;
courant = debut;
while(courant != NULL)
{
suiv = courant->suivant;
delete courant;
courant = suiv;
}
}
//---------------------------------------------------------------------------
/*inline liste :: liste(const liste &l)
{
a définir
}*/
//---------------------------------------------------------------------------
void liste :: ajoute(void *chose)
{
element *adel = new element;
adel->suivant = debut;
adel->contenu = chose;
debut = adel;
}
//---------------------------------------------------------------------------
void liste :: premier()
{
courant = debut;
}
//---------------------------------------------------------------------------
void * liste :: prochain()
{
void * adel = NULL;
if(courant != NULL)
{
adel = courant->contenu;
courant = courant->suivant;
}
return adel;
}
//---------------------------------------------------------------------------
int liste :: fini()
{
return (courant == NULL);
}
//---------------------------------------------------------------------------
/*
*/
class point
{
int x;
int y;
public :
inline point(int abs, int ord);
inline point(const point &);
inline point & operator =(const point &);
inline ~point();
inline void affiche();
};
//---------------------------------------------------------------------------
inline point :: point(int abs=0, int ord=0)
{
x = abs;
y = ord;
}
//---------------------------------------------------------------------------
inline point :: point(const point &pt)
{
x = pt.x;
y = pt.y;
}
//---------------------------------------------------------------------------
inline point & point :: operator =(const point &pt)
{
if(&pt != this)
{
x = pt.x;
y = pt.y;
}
return *this;
}
//---------------------------------------------------------------------------
inline point :: ~point()
{
}
//---------------------------------------------------------------------------
void point :: affiche()
{
cout << "Coordonnees : " << x << " " << y << "\n";
}
//---------------------------------------------------------------------------
/*
*/
class liste_points : public liste, public point
{
public :
liste_points() {}
void affiche();
};
//---------------------------------------------------------------------------
void liste_points :: affiche()
{
premier();
while( ! fini() )
{
point *ptr = (point*) prochain();
ptr->affiche();
}
}
//---------------------------------------------------------------------------
#endif

**********************************************************

le main

//---------------------------------------------------------------------------
#include "multiple.h"
void f(liste);
//---------------------------------------------------------------------------
int main()
{
liste_points l, l_temp;
point a(2,3);
point b(5,9);
point c(0,8);
l.ajoute(&a);
l.affiche();
cout << "---------------------\n";
l.ajoute(&b);
l.affiche();
cout << "---------------------\n";
l.ajoute(&c);
l.affiche();
cout << "---------------------\n";
f(l);
return 0;
}
//---------------------------------------------------------------------------
void f(liste l)
{
}

13 réponses

Messages postés
351
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
12 août 2009

Tout d'abord, une chose me frappe :
void * liste :: prochain()
{
void * adel = NULL;
if(courant != NULL)
{
adel = courant->contenu;
courant = courant->suivant;
}
return adel;
}

Cette fonction n'est-elle pas censée renvoyer un pointeur sur un suivant ? Ou alors le nom est mal choisi ?!

Ensuite, si je comprend bien tu veux créé une liste composée d'éléments ou reprendre une liste déjà créée et sauvegardée. Me trompai-je ?

Dans ce cas tu dois recupérer un a un les éléments de ta liste sauvegardée et les affecter à ta nouvelle liste courante.

Je te conseille aussi d'ajouter un compteur d'élément dans ta liste
class MaListe
{

....

int NbreDelements;
int LeNbreDelementDeLaListe();

}//bien pratique pour les boucles;

Autre conseil dans ta notation : Utilise des Majuscules pour les noms de fonctions et variables et un 'p' devant pour les pointeurs:

struct Element
{
Element *pSuivant; // un pointeur sur l'élément suivant
void *pContenu; // un pointeur de type indéfini sur le contenu
};
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
il te faut egalement l'operateur =

a par ca c'est du c, le void * sert de pointeur generique uniquement en c, en c++ seul la conversion int* -> void* est implicite

oublie tout ce que tu a vue, lis un cours sur les template et utilise std::list
Messages postés
1878
Date d'inscription
jeudi 16 octobre 2003
Statut
Membre
Dernière intervention
16 mars 2011
1
si ça peut-t'aider lit mon source : BListeIndir...

Magic Nono: l'informagicien!
Messages postés
24
Date d'inscription
jeudi 6 mai 2004
Statut
Membre
Dernière intervention
21 janvier 2005

bein lorsque je déclare mon constructeur de telle sorte :

liste :: liste(const &l)

j'aimerai recopie l'objet référencé "l" dans la nouvelle liste qui est appele avec le constructeur de recopie...

je veux juste définir moi meme ce constructeur de rocopie pour pouvoir passer l'objet liste en parametre sans le referencer ou utiliser son adresse via un pointeur...

sinon je sais et connais l'utilisation des templates, conteneur et autres standards de la STL mais je voudrai tout faire comme un grand tout seul et réussir a, via le destructeur, enlever mes objets de la memoire dynamique sans provoquer d'erreur lorsque le destructeur est appele car avec mes essais il doit supprimer deux ou plusieurs fois le meme objet et donc creer une ambiguite
Messages postés
24
Date d'inscription
jeudi 6 mai 2004
Statut
Membre
Dernière intervention
21 janvier 2005

"Cette fonction n'est-elle pas censée renvoyer un pointeur sur un suivant ? Ou alors le nom est mal choisi ?!

Ensuite, si je comprend bien tu veux créé une liste composée d'éléments ou reprendre une liste déjà créée et sauvegardée. Me trompai-je ?"

je veux juste effectuer une recopie de ma liste lorsqu'elle est passee en parametre dans une fonction quelconque pour ne pas la passer en reference ou via son pointeur, c'est tout comme je l'ai fait pour l'objet point :

point :: point(const point &P)
{
x = P.x ;
y = P.y ;
}

voila... mais en faisant mes essai je la recopie tres mal et surtout je detruit le meme objet plusieurs fois en sortie de fonction ou du main via le destructeur qui ne peut "delete" un pointeur sur NULL

: ) : ) :)
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
pour ton constructeur par copie, tu parcour la liste en parametre et tu insert les elements parcourues
il faut aussi que tu rajoute l'operateur = si tu veux que ta classe soit proteger contre les fuites

ne fais jamais ca

point :: point(const point &P)
{
x = P.x ;
y = P.y ;
}

c'est de la desoptimisation, le compilo le fait tres bien, et meme mieux tout seul
Messages postés
351
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
12 août 2009

" je detruit le meme objet plusieurs fois en sortie de fonction ou du main via le destructeur qui ne peut "delete" un pointeur sur NULL"

if(MonPointeur !=NULL)
delete MonPointeur;
Messages postés
24
Date d'inscription
jeudi 6 mai 2004
Statut
Membre
Dernière intervention
21 janvier 2005

"ne fais jamais ca

point :: point(const point &P)
{
x = P.x ;
y = P.y ;
}

c'est de la desoptimisation, le compilo le fait tres bien, et meme mieux tout seul"

a bon ce n'est pas bon de definir le const. de recopie comme je l'ai fait... ?

en gros le compilo le fait mieux que ça :

[inline point :: point(const point &pt)
{
x = pt.x;
y = pt.y;
}
//---------------------------------------------------------------------------
inline point & point :: operator =(const point &pt)
{
if(&pt != this)
{
x = pt.x;
y = pt.y;
}
return *this;
}
]

pour la recopie et l'affectation ?

sinon comment parcourir ma liste en parametre puisqu'elle est constante ?

merci de ton suivi : ) : ) :)
Messages postés
351
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
12 août 2009

liste :: liste(const &l)
{

liste *pNouvelleListe = new liste;

pNouvelleListe->Ajouter(l->Premier());
while(/*condition qui va bien*/)
pNouvelleListe->Ajouter(l->Prochain());

}

?? peut-être
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
popi0016 > ne redefinie jamais cnstructeur par copie et operateur = quand il s'agit juste de faire une copie des membres (pas d'alllocation ou autre)

le compilo les generes lui meme, tu pourra pas faire plus optimisé que sa copie de bas niveau
Messages postés
24
Date d'inscription
jeudi 6 mai 2004
Statut
Membre
Dernière intervention
21 janvier 2005

merci du conseil : ) : ) : )

et la solution du dessus semble etre bonne je vais essayer, merci a tous : ) : ) : )
Messages postés
24
Date d'inscription
jeudi 6 mai 2004
Statut
Membre
Dernière intervention
21 janvier 2005

[pour ton constructeur par copie, tu parcour la liste en parametre et tu insert les elements parcourues
il faut aussi que tu rajoute l'operateur = si tu veux que ta classe soit proteger contre les fuites]

comment t'y prendrais tu car la solution proposee par thierry la fronde n'est pas adequate et provoque des exeptions... car ma liste a recopie est elle constante et je ne peux donc modifier aucun membre de celle-ci ???

:) :) :)
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
d'une maniere generale, declare des pointeurs en local pour parcourir a liste sans la modifié (comme l'exemple de thierry la fronde, mais adapté à ta liste si ca ne l'est pas)