polymorphisme et template

polymorphisme et template - C++ - Programmation

Marsh Posté le 30-12-2002 à 15:34:00    

bon on va peut etre y arrive cette fois :
 
Je dois gérer un gestionnaire de memoire un peu complexe.
Pour commencer, j'ai besoin d'une classe Pool, template, qui permet de gérer des tableaux statiques de types T :
 

Code :
  1. template<typename T> class Pool
  2. {
  3.     public:
  4.     class UninitializedMemory        {};
  5.     class AlreadyInitializedMemory {};
  6.     class MemoryFull     {};
  7.     class InvalidPointer {};
  8.     Pool()
  9.     {
  10.         data    = (T*)0L;
  11.         maxSize = 0;
  12.     }
  13.    
  14.     ~Pool()
  15.     {
  16.         cleanup();
  17.         data    = (T*)0L;
  18.         maxSize = 0;
  19.     }
  20.     void initialize( unsigned long size )
  21.     {
  22.         Assert<AlreadyInitializedMemory>( !data );
  23.         maxSize = size;
  24.         data = new T[size];
  25.         firstValid = data;
  26.         lastValid = data+size;
  27.     }
  28.     void cleanup()
  29.     {
  30.         Assert<UninitializedMemory>( data != (T*)0L );
  31.         delete[] data;
  32.         firstValid = lastValid = (T*)0L;
  33.     }
  34.     T* acquire()
  35.     {
  36.         Assert<UninitializedMemory>( data != (T*)0L );
  37.         if( firstValid != lastValid )
  38.         {
  39.             return firstValid++;
  40.         }
  41.         else if( !freeSpace.empty() )
  42.         {
  43.             T* tmp = freeSpace.front();
  44.             freeSpace.pop();
  45.             return tmp;
  46.         }
  47.         else
  48.         {
  49.             throw MemoryFull();
  50.         }
  51.     }
  52.     void release( T* ptr )
  53.     {
  54.         Assert<InvalidPointer>( ptr != (T*)0L );
  55.         if( ptr == (firstValid-1) )
  56.         {
  57.             firstValid = ptr;
  58.         }
  59.         else
  60.         {
  61.             freeSpace.push( ptr );
  62.         }
  63.     }
  64.     private:
  65.     T*              data;
  66.     T*              firstValid;
  67.     T*              lastValid;
  68.     queue<T*>       freeSpace;
  69.     unsigned long   maxSize;
  70. };


 
bon le truc ce que je veux pouvoir gérer des Pool<int>, Pool<char>, Poll<Classe> etc ...
Donc dans mon gestionnaire de memoire je vais mettre un truc du style :
 

Code :
  1. map< string, Pool*>


 
Mais est ce bon ?
Je penseez rajouter une interface du style :
 

Code :
  1. class IPool 
  2. {
  3.     public:
  4.     virtual void initialize( unsigned long size ) = 0;
  5.     virtual void cleanup() = 0;
  6.    
  7.     // pas bon mais que mettre ??
  8.     virtual void* acquire( unsigned long nb ) = 0;
  9.     virtual void release( void* ptr ) =0;
  10. };


 
et faire heriter Pool<T> de IPool.
 
Manque de bol, ca chie, impossible d'appeler le bon Pool a partir d'un IPool*
 

Code :
  1. IPool* tab[2];
  2. Pool<int> intPool;
  3. Pool<float> floatPool;
  4. tab[0] = &intPool;
  5. tab[1] = &floatPool;
  6. // Ca plante
  7. int *a = (dynamic_cast<Pool<int>*>tab[0])->acquire(1);


 
Pliz help :)

Reply

Marsh Posté le 30-12-2002 à 15:34:00   

Reply

Marsh Posté le 30-12-2002 à 15:57:21    

Bon apparemment ca vient de Visual 6.0
Sous GCC ca amrche ...
Bizarre !!

Reply

Marsh Posté le 30-12-2002 à 18:01:39    

Joel F a écrit :

Bon apparemment ca vient de Visual 6.0
Sous GCC ca amrche ...
Bizarre !!


C'est bizarre, je vois pas de problème... Quand tu utilises de debugger de Visual C++ en pas à pas pour le dynamic_cast, que vois-tu ?
Quel service pack de Visual as-tu ?
 
Au fait, y a des techniques plus efficaces pour gérer des pools, surtout quand les objets contenus sont petits...
Par exemple en se débrouillant pour que chaque objet du pool soit:
- un objet du pool (T)
- un noeud de liste chainee
Après tu alloues tes éléments par paquets (genre new T[128])
 
Mais bon plein de gens ont déja fait des libs de pool d'objets de taille fixe, tu devrais jeter un coup d'oeil sur google

Reply

Marsh Posté le 30-12-2002 à 18:10:16    

VC6 est loin d'être au top pour le support des templates.

Reply

Marsh Posté le 30-12-2002 à 21:32:00    

merci a tous de tte maniere, je v jeter VC6 pr wxWindows+gcc.
En tout cas, mon Pool est bien pour ce que je fais donc bon ...
J'aime bien faire les choses par moi-meme :)

Reply

Marsh Posté le 31-12-2002 à 08:42:51    

Joel F a écrit :

merci a tous de tte maniere, je v jeter VC6 pr wxWindows+gcc.
En tout cas, mon Pool est bien pour ce que je fais donc bon ...
J'aime bien faire les choses par moi-meme :)


 
question bête quand même: sous visual, le support RTTI n'est pas activé par défaut. Tu l'as activé avant de compiler? Sinon, c'est normal que ca crash.
Ceci dit, je ne te retiens pas pour jeter VC6!

Reply

Marsh Posté le 31-12-2002 à 08:54:41    

le pb de vc6 c'est qu'il est indispensable lorsque l'on utilise une dll tierce, non ? (je pense aux histoires de mangling C++)

Reply

Marsh Posté le 31-12-2002 à 10:12:32    

hmmm le support RTTI n'a rien changer ...

Reply

Marsh Posté le 31-12-2002 à 10:32:36    

bon a part ca mon Memory Manager rencontre un e probleme
 
j'utilise une class Handle<T> pour etre un descripteur des objets allouées dand les Pool<T>. Une class MemoryManager gere des groupes de Pool<T> via une map<id,IPool*>.
 
en clair, l'utilisateur pond un truc du style
 

Code :
  1. // on suppose que ttes l'init et les dclarations de classes
  2. // sont correctes.
  3. // Va chercher un bloc memoire dans le Pool<String> du MM;
  4. // et l'initialise.
  5. Handle<String> b;
  6. *b = "Ma chaine ...";
  7. b->method();
  8. // ici A herite de BaseA ..
  9. Handle<A> classeA;
  10. Handle<BaseA> classeBaseA;
  11. classeBaseA = claseeA; // CA PLANTE !


 
Comment gerer l'heritage via le systeme de Pool ???
Dois je autorise des affectations du style :
 
template<T2>
Handle<T> operator=(const Handle<T2>& src);
 
et verifier si il existe une conversion explixite de T2 vers T ??

Reply

Marsh Posté le 31-12-2002 à 12:01:29    

Lolo- a écrit :

le pb de vc6 c'est qu'il est indispensable lorsque l'on utilise une dll tierce, non ? (je pense aux histoires de mangling C++)


Ben disons plutot qu'il est indispensable quand on utilise une dll tierce crée avec Viual C++. Ca doit etre la meme chose chez Borland...

Reply

Marsh Posté le 31-12-2002 à 12:01:29   

Reply

Marsh Posté le 01-01-2003 à 00:02:11    

kenshiro182 a écrit :


C'est bizarre, je vois pas de problème... Quand tu utilises de debugger de Visual C++ en pas à pas pour le dynamic_cast, que vois-tu ?


 
c'est bizarre perso je vois plein de problemes potentiels
 
deja IPool n'est pas une interface consistante avec Pool<T>
 
acquire ne peux pas etre differenciee sur le type de retour (c'est une base de la surcharge en C++) donc au mieux, acquire() dans IPool ne sert a rien au pire c'est un bug ou alors il n'a pas poste son bon code. D'autant plus qu'il appelle acquire de IPool qui n'est pas initialise (classe abstraite) dans son exemple.
 
Ensuite la syntaxe du dynamic cast
c'est avec les ()
exemple:
dynamic_cast<toto*>(tutu);
 
Ensuite les exceptions qu'il jette sont des sous-classes de la classe template.
Difficile de les intercepter dans ce cas sans savoir quel type de pool a balance l'exception (a moins de les faire deriver d'une classe d'exception plus globale).
 
Bon supposons qu'il n'y ait pas tous ces problemes :
acquire appele sur un pool initialise avec le constructeur par defaut jettera MemoryFull, puisque FreeMemory n'a pas ete touche depuis sa construction..
 
Bref il faudrait avoir le vrai code pour juger a mon avis..
 
LeGreg


Message édité par LeGreg le 01-01-2003 à 00:02:49

---------------
voxel terrain render engine | animation mentor
Reply

Marsh Posté le 01-01-2003 à 14:28:10    

legreg a écrit :


c'est bizarre perso je vois plein de problemes potentiels


Ouh la la j'ai pas les yeux en face des trous. Ou alors j'ai regardé trop vite. Honte sur moi !

Reply

Marsh Posté le 01-01-2003 à 19:46:34    

euh desole, j'ai oublie de corriger (j'etais ds le colatre) mais :
 

Code :
  1. template<class T> Pool : public IPool


 
et
 

Code :
  1. IPool* tab[2];
  2. Pool<int> intPool;
  3. Pool<float> floatPool;
  4. tab[0] = &intPool; 
  5. tab[1] = &floatPool;
  6. intPool->initialize( 500 );
  7. // Ca plante  
  8. int *a = (dynamic_cast<Pool<int>*>tab[0])->acquire(1);


 
et je confirme que sous Gcc ca compile propre en -Wall -ANSI -pedantic et que surtout ca s'execute correctement.
 
La classe interne d'exception dans un template ca ne pose PAS de probleme :
 

Code :
  1. try
  2. {
  3. ....
  4. }
  5. catch( Pool<int>::MemoryFull )
  6. {
  7. ...
  8. }


Message édité par Joel F le 01-01-2003 à 19:48:42
Reply

Marsh Posté le 01-01-2003 à 20:55:17    

pourquoi tu ne mets pas tout ton code plutot que des bouts ?
 
Ta methode initialize n'est pas complete.
acquire de IPool et de Pool ont des sens differents
et je ne suis pas trop sur que tu aies resolu l'ambiguite..
 
Et tu n'as pas corrige la syntaxe du "dynamic_cast<toto*>(bidule);" meme si gcc te laisse compiler c'est une erreur de sa part. En tout cas je ne suis pas sur que visual te laisse faire.
 

Code :
  1. int *a = dynamic_cast<Pool<int>*>(tab[0])->acquire(1);


me semble plus correct.
 
Pour la classe interne d'exception ca ne pose effectivement pas de probleme si c'est comme ca que tu l'utilises. Ceci dit, question de gouts..
 
LeGreg


---------------
voxel terrain render engine | animation mentor
Reply

Marsh Posté le 01-01-2003 à 23:54:11    

desole de poster des fragments de code, le pb c'est qu'il y a pas mal de parties de ce trucs qui sont sensées restaient confidentielles ou qui sont trop volumineuses donc bon ...
 
N'empeche, effectivement, la correction du dynamic_cast etait necessaire mais l'ambiguite est bien levée.
 
gcc compile, Visual aussi masi visual fait n'importequ'oi apres donc... Bref, merci encore.
 
Promis le prochain bout de code que je poste il est propre et complet  [:joel f]

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed