Les iterateurs en c++ Help me !

Résolu
cs_Saris Messages postés 24 Date d'inscription mardi 14 novembre 2000 Statut Membre Dernière intervention 28 octobre 2006 - 27 févr. 2006 à 16:45
cs_Saris Messages postés 24 Date d'inscription mardi 14 novembre 2000 Statut Membre Dernière intervention 28 octobre 2006 - 28 févr. 2006 à 15:59
Bonjour à tous,

J'suis bien embèté car je capte pas grand chose au fonctionnement des itérateurs ou plutôt à l'utilité de ceux-ci dans mon projet pour l'école...

Je dois créer une classe arbre générique. Pour se faire j'utilise les templates. Ca ya pas de problème.
voici ma classe:

//---------------------------------------------------------------------------
// Fichier : ArbreGenerique.h
//
// Auteur : Jérémy Counet
//
// Date de création : 20/11/05
// Dernière mise à jour : 22/02/06
//
// Description :
// Création d'un Arbre générique qui pourra être utilisé à souhait.
//---------------------------------------------------------------------------


#ifndef ArbreGenerique_H
#define ArbreGenerique_H


#include <string>
#include <list>
#include


//---------------------------------------------------------------------------
using namespace std;


/****************************************************************************
* Class Arbre Générique
****************************************************************************/
template<class T> class Arbre
{
class Noeud
{
private:
// Valeur contenue dans un Noeud
T _valeur;


// Noeud père
Noeud* _pere;


// List contenant tous les Fils
list<Noeud*> _lFils;


public:
// Constructeurs
Noeud();
Noeud(T &v);


// Destructeur
~Noeud();


// Retourne le père du noeud
Noeud* getPere(void);


// Retourne la caleur contenue dans le Noeud
T& getValeur(void);


// Donne les fils (la liste) du noeud passé en paramètre
list<Noeud*>& getFils(void);
};


private:
Noeud* _racine;


public:
// Constructeurs
Arbre(void);


// Destructeur
~Arbre(void);


// Donne la racine de l'arbre
Noeud* getRacine(void);


// Insère un noeur de type T dans l'arbre
bool bInsererNoeud(Noeud* pere, Noeud* newFils);


// Insère un noeud de type T dans l'arbre à un endroit bien précis du
// vecteur fils du père
bool bInsererNoeud(Noeud* pere, Noeud* newFils, int iIndex);
};
//---------------------------------------------------------------------------


/****************************************************************************
* Méthodes de la classe Noeud
****************************************************************************/
//---------------------------------------------------------------------------
// Constructeur par défaut
//---------------------------------------------------------------------------
template<class T>
Arbre<T>::Noeud::Noeud()
{
_pere = NULL;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Constructeur
// IN : v - valeur à initialiser dans le Noeud
//---------------------------------------------------------------------------
template<class T>
Arbre<T>::Noeud::Noeud(T &v)
{
_valeur = v;
_pere = NULL;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Le Destructeur
//---------------------------------------------------------------------------
template<class T>
Arbre<T>::Noeud::~Noeud()
{
_lFils.clear();
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Donne le père du Noeud
// IN : void
// OUT : _pere - pointeur vers le père du Noeud
//---------------------------------------------------------------------------
template<class T>
Noeud* Arbre<T>::Noeud::getPere(void)
{
return _pere;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Donne la Valeur contenue dans le Noeud
// IN : void
// OUT : T _valeur - valeur de type T
//---------------------------------------------------------------------------
template<class T>
T& Arbre<T>::Noeud::getValeur(void)
{
return _valeur;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Donne les fils (le vecteur) du Noeud passé en paramètre
// IN : pere - Noeud père dont on souhait récupérer ses fils
// OUT : _lFils - liste contenant tous les fils du Noeud père
//---------------------------------------------------------------------------
template<class T>
list::Noeud*>& Arbre<T>::Noeud::getFils(void)
{
return _lFils;
}
//---------------------------------------------------------------------------

/****************************************************************************
* Méthodes de la classe Arbre
****************************************************************************/
//---------------------------------------------------------------------------
// Constructeur
// IN : void
//---------------------------------------------------------------------------
template<class T>
Arbre<T>::Arbre(void)
{
_racine = new Noeud();
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Le Destructeur
//---------------------------------------------------------------------------
template<class T>
Arbre<T>::~Arbre(void)
{
delete _racine;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Donne la racine de l'arbre (Le pointeur "Noeud" pointant vers le premier
// élément de l'arbre générique).
// IN : void
// OUT :
//---------------------------------------------------------------------------
template<class T>
Noeud* Arbre<T>::getRacine(void)
{
return _racine;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Insère un nouveau Noeud dans l'arbre
// IN : pere - Noeud père du nouveau Noeud à insérer
// newFils - Nouveau Noeud à insérer
// OUT : Vrai si le nouveau Noeud a été insérer
//---------------------------------------------------------------------------
template<class T>
bool Arbre<T>::bInsererNoeud(Noeud* pere, Noeud* newFils)
{
bool bInsert = true;
int i=-1;
vector ::Noeud*>& vFils = pere->getFils();


try
{
vFils.resize(pere->getFils().size()+1, newFils);
}
catch (...)
{
cout << "Erreur d'insertion dans inserNoeud1" << endl;
bInsert = false;
}


return bInsert;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Insère un nouveau Noeud dans l'arbre
// IN : pere - Noeud père du nouveau Noeud à insérer
// newFils - Nouveau Noeud à insérer
// iIndex - index où sera inséré le nouveau noeud dans le vecteur du père
// OUT : Vrai si le nouveau Noeud a été insérer
//---------------------------------------------------------------------------
template<class T>
bool Arbre<T>::bInsererNoeud(Noeud* pere, Noeud* newFils, int iIndex)
{
bool bInsert = true;


vector ::Noeud*>& vFils = pere->getFils();


try
{
vFils.resize(vFils.size()+1, newFils);
//vFils.insert(iIndex, newFils);
}
catch (...)
{
cout << "Erreur d'insertion dans inserNoeud2" << endl;
bInsert = false;
}


return bInsert;
}
//---------------------------------------------------------------------------


#endif

Le problème est que mon prof ne veut pas qu'une méthode public renvois un attribut privé.
Donc : Noeud* getRacine(void); n'est pas logique et la classe Noeud ne devrait pas être visible au utilisateur de ma classe générique. C'est pour ça qu'il me propose d'utiliser les iterateurs car c'est un principe important qu'utilise bcp la STL.

Pour getRacinde(), est ce que ceci serait correcte ?
iterator getRacine(void);

Je voudrais comprendre comment ces iterateur peuvent remplacer un objet d'un classe en l'occurence Noeud au lieu d'un contener? Et pour ma méthode getFils(void)? que dois-je faire ??
list<Noeud*>::iterator getFils(void);

Après je ne vois pas non plus comment réccupérer ces objets via un appel dans une autre classe qui hérite de ArbreGenerique ...

SVP aidez moi

MERCI!!!

9 réponses

vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
27 févr. 2006 à 17:09
Je crois qu'il serait très utile d'aller voir les sources de quelques modèles de la stl (par exemple list)
Ta va créer une classe interne iterator dans ton type arbre (on ne parle pas de noeud, c'est un type pour l'implémentation, qui doit être caché)
Après si tu as besoin de getFils, tu le définis pour ton itérateur. A la fin ca devrait ressembler à ca:
Arbre a;
Arbre::iterator i = a.racine();
i.getFils(); // ou i=i.getFils(), c'est a toi de voir comment tu le fais
cout << *i << endl;
3
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
27 févr. 2006 à 17:21
Dans ton cas, un itérateur reviendrait simplement à un pointeur sur un
noeud. Après, il faut fournir une quantité de fonction pour déplacer
cet itérateur dans ton arbre. Et notamment une fonction Value() qui
retournerait la valeur du noeud actuellement pointé par l'itérateur.
3
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
27 févr. 2006 à 17:37
A la place de Value() on peut définir l'opérateur * (à la manière de la STL)
3
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
28 févr. 2006 à 14:58
Tu obtiens ton itérateur avec une méthode de la classe arbre:

class Arbre<T> {
public:
class iterator {...};
iterator getRacine() {return iterator(racine);}
...
};
3

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

Posez votre question
cs_Saris Messages postés 24 Date d'inscription mardi 14 novembre 2000 Statut Membre Dernière intervention 28 octobre 2006
28 févr. 2006 à 14:27
je capte mieux le principe mais j'ai toujours des erreurs... c'est qu'en fin de compte j'ai pas tout bien compris.
J'ai donc créé ma classe iterator en public dans mon arbre.

voici cette classe : dite moi si je vais dans la bonne direction...

public:
class iterator
{
private :
Noeud* _it;


public :
iterator()
{
_it = _racine;
}


list<T>::iterator & getFils(void)
{
return (_it->getFils()).begin();
}


iterator getFils(int iIndex)
{
list<T>::iterator & lIt = this->getFils();


for (int i=0; i


return lIt;
}


iterator getPere()
{
_it = _it->getPere();
return this;
}


int nbrFils(void)
{
return _it->getFils().size();
}


T& operator* () const
{
return _it->getValeur();
}


void addNewFils(T* newFils)
{
list::Noeud*>& lFils = _it->getFils();
Noeud* newNoeud = new Noeud(newFils);


lFils.push_back(newNoeud);
}


void addNewFils(T* newFils, int iIndex)
{
list::Noeud*>& lFils = _it->getFils();
Noeud* newNoeud = new Noeud(newFils);


list::Noeud*>::iterator lIt = lFils.begin();
for (int i=0; i


lFils.insert(lIt, newNoeud);
}


void operator delete(void*)
{
delete _it;
}
};

Problème àla ligne en rouge : _racine ne peut pas être utilisé sans un objet.
Pourtant quand je crée un ArbreGénérique<T>::iterator it; celui-ci doit bien pointer vers le premier élément de mon arbre, donc ma racine ...Comment puis je réaliser ceci ?
Merci
0
cs_Saris Messages postés 24 Date d'inscription mardi 14 novembre 2000 Statut Membre Dernière intervention 28 octobre 2006
28 févr. 2006 à 15:08
Si je procède de la sorte, je vais devoir créer un constructeur iterator(Noeud*);
et vu que la classe iterator est en public, le Noeud sera alors visible de l'extérieur . . . chose que mon prof ne désire pas.
Est ce que je me trompe ?
0
cs_Saris Messages postés 24 Date d'inscription mardi 14 novembre 2000 Statut Membre Dernière intervention 28 octobre 2006
28 févr. 2006 à 15:24
Ce qui serait bien de faire, c'est que quand je crée un Arbre::iterator, le Noeud* de cet itérator pointe sur la racine par défaut.
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
28 févr. 2006 à 15:25
Rien ne t'empêche de mettre ton constructeur iterator(Noeud*) en private, comme ca Noeud n'est pas visible
0
cs_Saris Messages postés 24 Date d'inscription mardi 14 novembre 2000 Statut Membre Dernière intervention 28 octobre 2006
28 févr. 2006 à 15:59
mais alors il n'est plus accessible via une méthode de ma classe Arbre...
0
Rejoignez-nous