Constructeur de recopie et pointeur sur pointeur

popi0016 Messages postés 24 Date d'inscription jeudi 6 mai 2004 Statut Membre Dernière intervention 21 janvier 2005 - 12 août 2004 à 22:16
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 - 13 août 2004 à 23:49
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

cs_thierry la fronde Messages postés 351 Date d'inscription mercredi 21 juillet 2004 Statut Membre Dernière intervention 12 août 2009
13 août 2004 à 00:13
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
};
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
13 août 2004 à 07:06
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
0
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
13 août 2004 à 10:57
si ça peut-t'aider lit mon source : BListeIndir...

Magic Nono: l'informagicien!
0
popi0016 Messages postés 24 Date d'inscription jeudi 6 mai 2004 Statut Membre Dernière intervention 21 janvier 2005
13 août 2004 à 17:57
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
popi0016 Messages postés 24 Date d'inscription jeudi 6 mai 2004 Statut Membre Dernière intervention 21 janvier 2005
13 août 2004 à 18:03
"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

: ) : ) :)
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
13 août 2004 à 19:31
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
0
cs_thierry la fronde Messages postés 351 Date d'inscription mercredi 21 juillet 2004 Statut Membre Dernière intervention 12 août 2009
13 août 2004 à 22:25
" 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;
0
popi0016 Messages postés 24 Date d'inscription jeudi 6 mai 2004 Statut Membre Dernière intervention 21 janvier 2005
13 août 2004 à 22:28
"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 : ) : ) :)
0
cs_thierry la fronde Messages postés 351 Date d'inscription mercredi 21 juillet 2004 Statut Membre Dernière intervention 12 août 2009
13 août 2004 à 22:31
liste :: liste(const &l)
{

liste *pNouvelleListe = new liste;

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

}

?? peut-être
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
13 août 2004 à 23:11
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
0
popi0016 Messages postés 24 Date d'inscription jeudi 6 mai 2004 Statut Membre Dernière intervention 21 janvier 2005
13 août 2004 à 23:15
merci du conseil : ) : ) : )

et la solution du dessus semble etre bonne je vais essayer, merci a tous : ) : ) : )
0
popi0016 Messages postés 24 Date d'inscription jeudi 6 mai 2004 Statut Membre Dernière intervention 21 janvier 2005
13 août 2004 à 23:34
[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 ???

:) :) :)
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
13 août 2004 à 23:49
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)
0
Rejoignez-nous