Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
732 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Pointeurs intelligents et liste chainée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Pointeurs intelligents et liste chainée

n°1339116
Alban44
Posté le 04-04-2006 à 20:06:02  profilanswer
 

Bonjour,
 
Je voulais savoir si quelqu'un avait déjà implémenter une liste chainée avec des "smart pointers" ?
 
Je pensais faire quelque chose comme ça (tiré du chapitre 16 de la FAQ C++ Lite):

Code :
  1. class FredPtr;
  2. class Fred {
  3.     public:
  4.       static FredPtr create()             { return new Fred(); }
  5.       static FredPtr create(int i, int j) { return new Fred(i,j); }
  6.        // ...
  7.     private:
  8.       friend class FredPtr;      // Une classe amie  
  9.       unsigned count_;
  10.       Fred():count_(0);
  11.       Fred(int i, int j):count_(0);
  12.       FredPtr Suivant;
  13.        // ...
  14.     };
  15. class FredPtr {
  16.     public:
  17.       Fred* operator-> () { return p_; }
  18.       Fred& operator* ()  { return *p_; }
  19.       FredPtr(Fred* p)    : p_(p) { ++p_->count_; }   // p ne doit pas valoir NULL
  20.      ~FredPtr()           { if (--p_->count_ == 0) delete p_; }
  21.       FredPtr(const FredPtr& p) : p_(p.p_) { ++p_->count_; }
  22.       FredPtr& operator= (const FredPtr& p)
  23.             {  // NE CHANGEZ PAS L'ORDRE DE CES INSTRUCTIONS!
  24.                // (Cet ordre gère correctement le cas de l'auto-affectation)
  25.               ++p.p_->count_;
  26.               if (--p_->count_ == 0) delete p_;
  27.               p_ = p.p_;
  28.               return *this;
  29.             }
  30.     private:
  31.       Fred* p_;     // p_ ne vaut jamais NULL
  32.     };


Mais lors de la compilation il me met une erreur comme quoi le type de Suivant n'est pas défini (invalid use of undefined type et forward declaration of 'struct FredPtr') et le résultat des fonction create non plus...en somme il ne reconnait pas la classe FredPtr dans la classe Fred.
 
Qu'ai je fait de mal ?
 
Question subsidiaire : est ce une bonne idée de faire une liste chainée avec des "smart pointers" ?


Message édité par Alban44 le 04-04-2006 à 20:32:12
mood
Publicité
Posté le 04-04-2006 à 20:06:02  profilanswer
 

n°1339121
nargy
Posté le 04-04-2006 à 20:31:06  profilanswer
 

> est ce une bonne idée de faire une liste chainée avec des "smart pointers" ?
 
J'aurai tendance à dire non... les smart pointers ne devraient pas être stockés en dehors de la pile principale (sinon ils ne sont plus <<smart>> ). En plus c'est de la bidouille.

n°1339125
nargy
Posté le 04-04-2006 à 20:35:39  profilanswer
 

> class FredPtr;
Te permet d'utiliser des pointeurs (des vrais) sur FredPtr, sinon le compilo ne connait pas la taille de cette classe au moment où il essaye de compiler la classe Fred.

n°1339126
Alban44
Posté le 04-04-2006 à 20:36:14  profilanswer
 

nargy a écrit :

> est ce une bonne idée de faire une liste chainée avec des "smart pointers" ?
 
J'aurai tendance à dire non... les smart pointers ne devraient pas être stockés en dehors de la pile principale (sinon ils ne sont plus <<smart>> ). En plus c'est de la bidouille.


 
Ok je comprends, alors comment géré proprement une liste doublement chainée dont les noeuds sont eux-memes des listes chainées ?
 
Au bout d'un moment le prog crash.

n°1339131
Alban44
Posté le 04-04-2006 à 20:41:57  profilanswer
 

nargy a écrit :

> class FredPtr;
Te permet d'utiliser des pointeurs (des vrais) sur FredPtr, sinon le compilo ne connait pas la taille de cette classe au moment où il essaye de compiler la classe Fred.


 
Si je te comprends bien, il faut que mes fonctions create renvoient un FredPtr*...et dans ce cas je perds l'interet du "smart pointer" d'ou ta premiere réponse...C'est ça ?
 

n°1339134
nargy
Posté le 04-04-2006 à 20:45:46  profilanswer
 

Le meilleur moyen reste de bien cloisonner ton code:

  • tu fait un template de liste chaînée, que tu peut réutiliser à volonté,
  • il ya deux types de listes: autodelete ou pas, autodelete supprime les éléments lorsque la lise est détruite (gare aux pointeurs qui traînent, les smart pointers ne t aideront pas), tu peut passer <bool autodelete> à un template,
  • tu gère proprement la destruction de tes objets.

n°1339136
Alban44
Posté le 04-04-2006 à 20:49:34  profilanswer
 

Merci de ton aide car sans ça je m'orientais vers une impasse.

n°1339139
nargy
Posté le 04-04-2006 à 20:55:24  profilanswer
 

Un exemple, avec autodelete en dehors du template, mais tu peut le modifier pour linclure dans le template (différence: ne peut changer l autodelete au runtime, mais plus optimisé).
 

Code :
  1. template <class Element> class DList
  2. {
  3.   class DListCell
  4.   {
  5.     public:
  6.     Element* e;
  7.     DListCell* prev;
  8.     DListCell* next;
  9.   };
  10.   DListCell* _list;
  11.   DListCell* _last;
  12.   bool _autodelete;
  13.   public:
  14.   DList(bool autodelete=1):_list(0),_last(0),_autodelete(autodelete) {}
  15.   ~DList()
  16.   {
  17.     for(DListCell* c=_list;c;)
  18.     {
  19.       DListCell* next=c->next;
  20.       if (_autodelete) delete c->e;
  21.       delete c;
  22.       c=next;
  23.     }
  24.   }
  25.   void setAutoDelete(bool a)
  26.   { _autodelete=a; }
  27.   class Index
  28.   {
  29.     DListCell* _current;
  30.     Index(DListCell* c): _current(c) {}
  31.     public:
  32.     Index(): _current(0) {}
  33.     Index(DList<Element>* list): _current(list->_list) {}
  34.     Index& next()
  35.     {
  36.       if (_current)
  37.         _current=_current->next;
  38.       return *this;
  39.     }
  40.     bool end() const
  41.     { return !_current; }
  42.     Element* operator -> () const
  43.     { return _current->e; }
  44.     friend class DList<Element>;
  45.   };
  46.   Element* operator [] (const Index& i) const
  47.   { return i._current->e; }
  48.   Index append(Element* e)
  49.   {
  50.     DListCell* c=new DListCell();
  51.     c->e=e;
  52.     c->next=0;
  53.     c->prev=_last;
  54.     if(_last)
  55.     {
  56.       _last->next=c;
  57.       _last=c;
  58.     }
  59.     else
  60.       _list=_last=c;
  61.     return Index(c);
  62.   }
  63.   Element* remove(Index& i)
  64.   {
  65. if (!i._current) fprintf(stderr,"DList::Index: removeing null!\n" );
  66.     if (i._current)
  67.     {
  68.       DListCell* c=i._current;
  69.       Element* r=c->e;
  70.       if(c==_list)
  71.       {
  72.         _list=_list->next;
  73.         if (_list)
  74.           _list->prev=0;
  75.       }
  76.       else if (c==_last)
  77.       {
  78.         _last->prev->next=0;
  79.         _last=_last->prev;
  80.       }
  81.       else
  82.       {
  83.         c->next->prev=c->prev;
  84.         c->prev->next=c->next;
  85.       }
  86.       i._current=c->next;
  87.       return r;
  88.     }
  89.     return 0;
  90.   }
  91. };



Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Pointeurs intelligents et liste chainée

 

Sujets relatifs
creation massive de liste de distributionliste HTML incrémentable
Problemes sur excel : liste, liens[VBA] [Résolu] Liste de choix
Pointeurs sur fonction membre, héritage, toussa[C] Problème de pointeurs et d'allocation
[VBS] Liste des dossiers partagés sur un serveurclassement dans une liste box [pblm]
Excel facture vs liste deroulanteLes pointeurs en Java
Plus de sujets relatifs à : Pointeurs intelligents et liste chainée


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR