[c++] intérêt de cette classe? Réécriture de la STL...

intérêt de cette classe? Réécriture de la STL... [c++] - C++ - Programmation

Marsh Posté le 03-07-2007 à 17:52:53    

Bonjour,
 
Dans le projet sur lequel je travaille il existe des classes gérant des tableaux, des vecteurs, et autres classes de stockage. Hors je ne vois pas l'intérêt de ces classes à part de se passer de la STL. Je pense qu'à l'époque où elles ont été écrites le code de la STL ne compilait pas sur certaines machines HP ou IRIX. Mais aujourd'hui toutes les plateformes sur lesquelles je compile acceptent la STL.
 
A votre avis, dois-je continuer à utiliser ces classes pour rester homogène avec le reste du projet?
 
Question subsidiaire : serait-il intéressant d'encapsuler la STL dans des classes à moi?
 
 
Voilà un extrait de code pour que vous voyiez de quoi je parle:
 
 

Code :
  1. template<class T>
  2. class cl_Tableau
  3. {
  4.  
  5. public:
  6.   void   set( T *Values, int Dim )
  7.   {
  8.     resize(Dim);
  9.     for( int i = 0; i < Dim; i++ )
  10.       (*this)[i] = Values[i];
  11.   };
  12. cl_Tableau( float RatioIncrement = 1.2 )
  13.   {
  14.     _Dim = 0 ;
  15.     _Size = 0;
  16.     _Values = 0;
  17.     if ( RatioIncrement <= 1.0 )
  18.       RatioIncrement = 1.2;
  19.     _RatioIncrement = RatioIncrement;
  20.   };
  21.  
  22.   cl_Tableau( T *Values, int Dim, float RatioIncrement = 1.2 )
  23.   {
  24.     if ( RatioIncrement <= 1.0 )
  25.       RatioIncrement = 1.2;
  26.     _RatioIncrement = RatioIncrement;
  27.     _Dim = 0 ;
  28.     _Size = 0;
  29.     _Values = 0;
  30.    set(Values, Dim);
  31.   };
  32.  
  33.   virtual ~cl_Tableau()
  34.   {
  35.     if ( _Values )
  36.       delete [] _Values;
  37.   }
  38.   inline int    size() const
  39.   {
  40.     return _Size;
  41.   }
  42.   T*     values() const
  43.   {
  44.     return _Values;
  45.   };
  46.   /*------------------------------------------------------*/
  47.   /* surcharge de la conversion en tableau de T*.   */
  48.   /*------------------------------------------------------*/
  49.   operator T*() const
  50.   {
  51.     return values();
  52.   }
  53.   inline T& operator [] ( int i ) const
  54.   {
  55. #ifdef DEBUG
  56.     if ( i < 0 || i >= _Size )
  57.       throw (char*)"Bad indice";
  58.     else
  59. #endif
  60.       return _Values[i];
  61.   };
  62.   virtual void reallocTab( int NewDim )
  63.   {
  64.     if ( NewDim < 0 )
  65.       throw (char*)"Bad size";
  66.    
  67.     int DataSize = sizeof(T);
  68.    
  69.     T* NewValues = new T[NewDim];
  70.    
  71.     int i;
  72.     if ( NewDim <= _Size )
  73.     {
  74.       for ( i = 0 ; i < NewDim ; i++ )
  75.         memcpy(NewValues+i,_Values+i,DataSize);
  76.      
  77.     }
  78.     else
  79.       {
  80. for ( i = 0 ; i < _Size ; i++ )
  81.   memcpy(NewValues+i,_Values+i,DataSize);
  82.       }
  83.    
  84.     delete [] _Values;
  85.    
  86.     _Values = NewValues;
  87.     _Dim = NewDim;
  88.   }
  89.   void resize( int NewDim )
  90.   {
  91.     reallocTab( NewDim );
  92.     _Size = _Dim;
  93.   }
  94.  
  95.   int  pos( T &Ref )
  96.   {
  97.     int i = 0;
  98.    
  99.     while ( i < _Size && Ref != (*this)[i] )
  100.       i++;
  101.    
  102.     if ( i < _Size )
  103.       return i;
  104.     else
  105.       throw (char*)"cl_Tableau<T>::pos /// Not Found";
  106.   }
  107.   void add( T Value )
  108.   {
  109.     if ( _Size+1 >= _Dim )
  110.       reallocTab( 10 + _Dim * _RatioIncrement );
  111.     _Size ++;
  112.     memcpy(_Values+_Size-1,&Value,sizeof(T));
  113.   }
  114.   void add( cl_Tableau<T> &TabIn )
  115.   {
  116.     int i;
  117.     for ( i = 0 ; i < TabIn.size() ; i++ )
  118.       add( TabIn[i] );
  119.   }
  120.   void add_once( T Value )
  121.   {
  122.     int i;
  123.     for ( i = 0 ; i < _Size ; i++ )
  124.       if ( Value == _Values[i] )
  125. return;
  126.     add(Value);
  127.   }

Message cité 1 fois
Message édité par kaloskagatos le 03-07-2007 à 17:53:33

---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 03-07-2007 à 17:52:53   

Reply

Marsh Posté le 03-07-2007 à 20:15:08    

bof, j'espère que le constructeur de recopie et l'opérateur d'assignement traine plus bas.
virtual dans une template générique ? wtf ?
 
y'a qu'une seule raison pour ne pas utiliser la STL: c'est d'être sûr d'aller vraiment plus vite avec sa propre implémentation. et 99% du temps ce n'est pas justifié (je sais j'ai déjà fais le con moi aussi).
 
vu le reallocTab, bof t'as la même pénalité à la réallocation qu'un vector (deuxième séquence d'objets et recopie), en plus ça doit être foireux de temps en temps (vu memcpy, si l'objet crée des dépendences à son adresse à la création qu'il libère à la destruction, assignement, là ça foirera là le std::vector conservera la logique objet).
 

Reply

Marsh Posté le 03-07-2007 à 20:44:16    

Citation :

virtual dans une template générique ? wtf ?


 
Des objets de l'appli héritent de cette classe pour avoir les méthodes d'un tableau.
 
 
Après tout ce que tu me dis confirme mon sentiment. Merci.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 03-07-2007 à 22:51:48    

kaloskagatos a écrit :


Des objets de l'appli héritent de cette classe pour avoir les méthodes d'un tableau.


 
Autant un objet qui contient un tableau je veux bien, autant une classe qui est un tableau, ca reste restreint. En outre, avec un template, il vaut mieux se rapatrier sur des solutions types static olymorphism (via le Barton-Nackmann trick) ou stratégies templates.

Reply

Marsh Posté le 03-07-2007 à 23:27:43    

kaloskagatos a écrit :

Citation :

virtual dans une template générique ? wtf ?


 
Des objets de l'appli héritent de cette classe pour avoir les méthodes d'un tableau.
 
 
Après tout ce que tu me dis confirme mon sentiment. Merci.


 
j'imagine que ça puisse être utile, mais il doit y avoir moyen de passer une classe intermédiaire en principe.

Reply

Marsh Posté le 03-07-2007 à 23:47:48    

kaloskagatos a écrit :

Bonjour,
 
Dans le projet sur lequel je travaille il existe des classes gérant des tableaux, des vecteurs, et autres classes de stockage. Hors je ne vois pas l'intérêt de ces classes à part de se passer de la STL. Je pense qu'à l'époque où elles ont été écrites le code de la STL ne compilait pas sur certaines machines HP ou IRIX. Mais aujourd'hui toutes les plateformes sur lesquelles je compile acceptent la STL.
 
A votre avis, dois-je continuer à utiliser ces classes pour rester homogène avec le reste du projet?
 
Question subsidiaire : serait-il intéressant d'encapsuler la STL dans des classes à moi?
 
 
Voilà un extrait de code pour que vous voyiez de quoi je parle:
 
[...]
 


 
Je déteste ce genre de classes utilitaires "maison". Je sais, c'est pas un argument, disons que je parle d'expérience  :o Si tu développes un module de ton projet à partir de rien, tu ferais mieux d'utiliser la STL. A ta place même dans un code existant j'abandonnerais l'utilisation de ces classes pour tous les ajouts que je ferais (sans aller jusqu'à remplacer par la STL même dans le code existant, après tout si personne n'a jamais signalé de bug...).
 

bjone a écrit :

y'a qu'une seule raison pour ne pas utiliser la STL: c'est d'être sûr d'aller vraiment plus vite avec sa propre implémentation. et 99% du temps ce n'est pas justifié (je sais j'ai déjà fais le con moi aussi).


 
J'ai un collègue qui a fait ses propres map pour un composant d'optimisation discrète, il m'assure qu'elles vont bcp + vite que celles de la STL made by Microsoft. Mais bon, il est vraiment fort et il a un besoin très particulier je pense.

Reply

Marsh Posté le 04-07-2007 à 08:26:33    

boulgakov a écrit :


J'ai un collègue qui a fait ses propres map pour un composant d'optimisation discrète, il m'assure qu'elles vont bcp + vite que celles de la STL made by Microsoft. Mais bon, il est vraiment fort et il a un besoin très particulier je pense.


 
oui voilà si il a benché son implémentation.

Reply

Marsh Posté le 04-07-2007 à 09:26:21    

A priori ça n'a pas été écrit dans un souci d'optimisation, donc comme effectivement je fais un module indépendant je vais utiliser la STL.
 
Merci pour le Barton-Nackman trick, je ne connaissais pas.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 04-07-2007 à 09:58:40    

C'est ultra mauvais en plus comme implémentation, surtout si T n'est pas un POD, ça fout tout en l'air avec ces memcpy. Et y a surtout aucune protection contre la copie, toussa, ça doit faire du joli toi qui cherche les double free :)
 
Tu peux pas la réimplémenter en héritant private de std::vector<> ?
et définir des constructeur de copie / operator= privé aussi et voir ce que ça donne. Si ça compile pas, tu trouveras immédiatement des copie ?
et vyrre tout ces trucs inline aussi.

Reply

Marsh Posté le 04-07-2007 à 10:18:56    

Taz a écrit :

C'est ultra mauvais en plus comme implémentation, surtout si T n'est pas un POD, ça fout tout en l'air avec ces memcpy. Et y a surtout aucune protection contre la copie, toussa, ça doit faire du joli toi qui cherche les double free :)


 
Qu'est-ce que je risque à remplacer les memcpy par des std::copy ?
 
 

Taz a écrit :


Tu peux pas la réimplémenter en héritant private de std::vector<> ?


 
Je pourrais le faire en me faisant une batterie de tests unitaires, mais j'ai un peu peur d'injecter ça dans tout le projet si ça doit le rendre instable... Si y'a des merdes dans cette implémentation, peut-être qu'elles sont rattrapées ailleurs, du coup mon passage à la stl sera foireux :/
 

Taz a écrit :

et définir des constructeur de copie / operator= privé aussi et voir ce que ça donne. Si ça compile pas, tu trouveras immédiatement des copie ?  


 
trouver des copies indésirables/foireuses tu veux dire?
 

Taz a écrit :


et vyrre tout ces trucs inline aussi.


 
pourquoiiiii?  [:briseparpaing]  


Message édité par kaloskagatos le 04-07-2007 à 10:22:09

---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 04-07-2007 à 10:18:56   

Reply

Marsh Posté le 04-07-2007 à 10:38:40    

1) parceque memcpy, ça copie des octets, pas des objets
2) pas forcément. vu le travail que ça demande, ça vaut le coup de faire un essai. l'implémentation avec un std::vector<> est très simple. t'as moyen de diviser le volume du code par 4 et donc de bug. tout en gardant la même interface exacte.
3) oui, et des double delete surtout
4) parce que ça sert à rien d'inliner tout ça, sauf à bloater ton binaire et a pourir ton cache
5) je peux pas viendre travailler avec toi ?


Message édité par Taz le 04-07-2007 à 10:39:13
Reply

Marsh Posté le 04-07-2007 à 10:49:00    

1) ma question était dans l'autre sens : est-ce que je peux remplacer les memcpy par des std::copy sans risque?
[2,4]) ok ça me botte d'essayer
5) ok mais c'est moi qui porterais la culotte.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 04-07-2007 à 10:55:42    

1) oui. et surtout simplifier ce genre de bétises
#
    for ( i = 0 ; i < _Size ; i++ )
#
      memcpy(NewValues+i,_Values+i,DataSize);  
 
5) OK. Y a peut etre meme une prime à la cooptation

Reply

Marsh Posté le 04-07-2007 à 10:57:24    

4) le truc c'est sur tout d'avoir :
- un .h avec la définition de la classe et des trucs inline
- un .tpp avec les définitions des fonctions membre pas inline. mais comme c'est des template, bah il faut #include à la fin du .h. ça te permet de quand meme avoir une séparation logique.

Reply

Marsh Posté le 04-07-2007 à 11:31:48    

roger wilco


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 04-07-2007 à 11:45:33    

let me know as soon as your code and you're ready


Message édité par Taz le 04-07-2007 à 11:45:48
Reply

Sujets relatifs:

Leave a Replay

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