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

  FORUM HardWare.fr
  Programmation
  C++

  Methode template intelligente

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Methode template intelligente

n°1667386
Takahani
Posté le 07-01-2008 à 21:34:50  profilanswer
 

Bonjour,
 
Avant toutes choses, autant préciser que je n'y connais pas grand chose en prog et que ce que j souhaite est surement tordu ou irréalisable mais bon, j'y crois :)
 
Alors voila je souhaiterais avoir une méthode template dans une classe qui me renvoie une valeur d'un certain type, ce type étant définie par un attribut interne de la classe (un entier qui prend plusieurs valeurs ...)
Un peu de code sera sûrement plus parlant (j'espère :roll:)
 

Code :
  1. // en réalité ces définitions sont ailleurs, je les rajoute ici pour compréhension
  2. #define VTK_DOUBLE 1
  3. #define VTK_FLOAT 2
  4. #define VTK_INT 3
  5. class MaClasseA
  6. {
  7.     MaClasseA(void );
  8.     template <typename T> T GetData(const int index);
  9.     void *ptr;
  10.     int type;
  11. }
  12. void MaClasseA::MaClasseA(void)
  13. {
  14. // ImageData est une instance de la classe vtkImageData de la librairie VTK et cette méthode renvoie un pointeur de type void * qui pointe vers un grand tableau 1D.  
  15. // Le souci est que je ne peux pas savoir à l'avance de quel type seront les données, cela dépend des images.  
  16. // Les données sont chargées ailleurs et j'ai simplifié le code pour compréhension, en tout cas j'ai accès à l'instance ImageData depuis le constructeur de cette classe.
  17.     ptr=ImageData->GetDataPointer();
  18.    
  19.     // renvoi VTK_DOUBLE ou VTK_FLOAT ou autres
  20.     type=ImageData->GetScalarType();
  21. }
  22. template <typename T> T MaClasseA::GetData(const int index)
  23. {
  24.    switch (type)
  25.    {
  26.         case VTK_DOUBLE :
  27.             return static_cast<double *>(ptr)[index];
  28.             break;
  29.         case VTK_FLOAT :
  30.             return static_cast<float *>(ptr)[index];
  31.             break;
  32.         default :
  33.             break;
  34.     }
  35. }
  36. class MaClasseB : public MaClasseA
  37. {
  38.     MaClasseB();
  39.     void MaMethodeAuPif(void);
  40. }
  41. void MaClasseB::MaClasseB(void){;}
  42. void MaClasseB::MaMethodeAuPif(void)
  43. {
  44.     cout<<"Valeur du voxel 150 "<<GetData(50)<<endl;
  45. }


Tout le problème se situe sur cette dernière méthode qui ne fonctionne pas dans l'état (dommage !). Et je ne veux pas avoir à faire ce qui suit sans quoi l'intérêt de la méthode template est plus que limité !
 

Code :
  1. void MaClasseB::MaMethodeAuPif(void)
  2. {
  3.     switch (InstanceClasseA->GetType())
  4.    {
  5.         case VTK_DOUBLE :
  6.             cout<<"Valeur du voxel 150 "<<GetData<double>(50)<<endl;
  7.             break;
  8.         case VTK_FLOAT :
  9.             cout<<"Valeur du voxel 150 "<<GetData<float>(50)<<endl;
  10.             break;
  11.         default :
  12.             break;
  13.     }
  14. }


Est ce qu'il existe un moyen de récupérer ma valeur avec une seule fonction, sans passer par le switch case ? Ca serait pas mal car je vais avoir énormément de méthodes du type [B]MaMethodeAuPif [/B]dans différentes classes qui héritent de MaClasseA, et je voudrais éviter le switch avec les 15 types à chaque fois ...
 
Voila merci d'avance et redites si c'est incompréhensible ou autres
Bonne soirée et merci pour votre forum riche en information
Simon


Message édité par Takahani le 07-01-2008 à 21:36:43
mood
Publicité
Posté le 07-01-2008 à 21:34:50  profilanswer
 

n°1667388
Joel F
Real men use unique_ptr
Posté le 07-01-2008 à 21:41:34  profilanswer
 

bah, un template c'ets purement statique, donc défini à la compilation. La ca ne te sera d'aucune utilité.

 

Le simple fait que tu fasse un switch sur un indicateur de type montre qu'il y a un defaut. Il fuat ici utiliser le polymorphisme

 

Sinon un bête :

 
Code :
  1. template <typename T> T MaClasseA::GetData(const int index)
  2. {
  3.    return static_cast<T*>(ptr)[index];
  4. }
 

solutionne le pb sans pouvoir faire de check.
De toute façon stocker un void* et transtyper derriere c'est moche.
Assure toi que contruire un MaClasse<T> renvoit un T* et basta

 

Edit : Ah , VTK c'est has been niveau lib.


Message édité par Joel F le 07-01-2008 à 21:52:18
n°1668374
Takahani
Posté le 09-01-2008 à 16:11:37  profilanswer
 

Bonjour, merci pour la réponse. Effectivement le polymorphisme sera surement plus adapté, mais je ne m'en sort toujours pas ... Des que je charge une image, je voudrais instancier une classe fille, qui hérite d'une classe mere, et ainsi faire fonctionner le polymorphisme. Seulement comment peut-on déclarer des méthodes dans les classes filles, qui n'ont pas le même constructeur que les classes mères ? J'entend pas la des méthodes surchargées qui ne renvoient pas le même type que la méthode virtuelle de la classe mère ?
 
Voici des bouts de code que je souhaiterais utiliser, mais je bloque :
 

Code :
  1. class AccessData{
  2. protected:
  3.     void* pData;
  4. public:
  5.     AccessData(void* data) {pData=data; }
  6.     virtual void GetData(int x, ...);
  7. };
  8. class Access_Char : public AccessData {
  9. public:
  10.     Access_Char(void* data):AccessData(data){;}
  11.     virtual char GetData(int x){return static_cast<char*>(pData)[x];}
  12. };
  13. class Access_Unsigned_Char : public AccessData {
  14. public:
  15.     Access_Unsigned_Char(void* data):AccessData(data){;}
  16.     virtual uchar GetData(int x){return static_cast<uchar*>(pData)[x];}
  17. };


Puis dans une autre classe, j'aurai un pointeur vers AccessData
 

Code :
  1. AccessData *pData;


Et au moment du chargement des l'images, je pourrai alors faire un :
 

Code :
  1. int nDataInType=ImageDataInput->GetScalarType();
  2.     switch (nDataInType)
  3.     {
  4.         case VTK_CHAR :
  5.             pDataIn=new Access_Char(pDataInput);
  6.             break;
  7.         case VTK_UNSIGNED_CHAR :
  8.             pDataIn=new Access_Unsigned_Char(pDataInput);
  9.             break;
  10.            
  11.         case VTK_SHORT :
  12.             pDataIn=new Access_Short(pDataInput);
  13.             break;   
  14.     }


Et ainsi pouvoir de n'importe où appeler ma valeur au pixel x avec la méthode GetData(x);
 
Malheureusement cela ne fonctionne pas, je reçois une erreur au compilateur du type :
erreur: valeur void n'a pas été ignorée comme elle aurait dû l'être
 
Forcément il s'attend à un retour de type void. Comment faire ? Il faut mélanger des templates avec cette architecture  :??:  ?
 
Merci si kkun sait faire ça  :jap:

n°1668400
Joel F
Real men use unique_ptr
Posté le 09-01-2008 à 16:31:59  profilanswer
 

rencadre toi sur le Design pattern Factory et Abstract Factory ;)

n°1668409
Takahani
Posté le 09-01-2008 à 16:37:03  profilanswer
 

Oui c'est sur mon programme n'ets pas super bien pensé mais bon, je suis pas programmeur, ce qui m'intéresse c'est la facilité d'utilisation du code :)
 
Et comme je suis très dépendant de VTK -pas si mal au passage ;), pour l'imagerie médicale, je ne connais pas mieux !-
Et bien je dois faire avec leur fichu pointeur de donnée en void*  
Je vais creuser encore un peu !
merci de l'aide en tout cas !

n°1668435
Joel F
Real men use unique_ptr
Posté le 09-01-2008 à 16:51:02  profilanswer
 

Takahani a écrit :

Oui c'est sur mon programme n'ets pas super bien pensé mais bon, je suis pas programmeur, ce qui m'intéresse c'est la facilité d'utilisation du code :)


 
Les DP n'ont aucun rapprot avec quoique se soit. C'ets juste de sméthodes éprouvées. La typiquement tu as besoin d'une factory
http://fr.wikipedia.org/wiki/Fabri [...] ception%29

n°1668455
Takahani
Posté le 09-01-2008 à 17:04:26  profilanswer
 

Merci, je ne connaissais pas du tout ce procédé !
Effectivement pour la construction ça va me simplifier la tache, par contre derriere il me faut toujours une méthode virtuelle qui renvoie un type générique pour la classe mère (AccessData) et des méthodes virtuelles filles qui elles renvoient respectivement des valeurs de types différents. Pour la méthode GetData() je ne vois pas bien encore comment faire  (suis vraiment un boulet, dsl ...)
Mais bon au moins j'apprends un peu ;)

n°1668460
Joel F
Real men use unique_ptr
Posté le 09-01-2008 à 17:07:35  profilanswer
 

regarde l'exemple sur wiki, c'est un truc qui s'appelle ImageReader ;)

n°1668488
Takahani
Posté le 09-01-2008 à 17:28:20  profilanswer
 

Ok j'ai donc fabriqué une classe :
 

Code :
  1. class FabriqueAccess{
  2. public:
  3.     AccessData* GetAccess(int type, void *data)
  4.     {
  5.         switch (type)
  6.         {
  7.             case VTK_DOUBLE :
  8.                 return new Access_Double(data);
  9.                 break;
  10.             case VTK_FLOAT :
  11.                 return new Access_Float(data);
  12.                 break;
  13.         }
  14.     }
  15. };


Avec les autres classes :

Code :
  1. class AccessData{
  2. protected:
  3.     void* pData;
  4. public:
  5.     AccessData(void* data) {pData=data; }
  6.     virtual void GetData(int x);
  7. };
  8. class Access_Float : public AccessData {
  9. public:
  10.     Access_Float(void* data):AccessData(data){;}
  11.     virtual float GetData(int x){return static_cast<float*>(pData)[x];}
  12. };
  13. class Access_Double : public AccessData {
  14. public:
  15.     Access_Double(void* data):AccessData(data){;}
  16.     virtual double GetData(int x){return static_cast<double*>(pData)[x];}
  17. };


Et comme ça pour instancier la classe je n'ai besoin que des lignes :

Code :
  1. FabriqueAccess *fa=new FabriqueAccess();
  2. pDataIn=fa->GetAccess(nDataInType, pDataInput);


Ca ça fonctionne nickel merci du tuyau c'est effectivement plus propre avec la factory  :jap:  
 
 
Par contre mon gcc ne veut pas compiler car la méthode GetData de la classe mere AccessData renvoit un void et que les autres méthode filles Access_Double et tout renvoi kkchose de différents. Il me donne une erreur du type :
 

Code :
  1. erreur: conflicting return type specified for «virtual double Access_Double::GetData(int)"
  2. erreur: overriding «virtual void AccessData::GetData(int)&


Désolé d'éprouver ta patience, si tu en as marre c'est pas grave, je comprendrai  :whistle:

n°1668493
Joel F
Real men use unique_ptr
Posté le 09-01-2008 à 17:31:31  profilanswer
 

fait une méthode abstraite
 

Code :
  1. class AccessData{
  2. protected:
  3.     void* pData;
  4. public:
  5.     AccessData(void* data) {pData=data; }
  6.     virtual int GetData(int x) = 0;
  7. };

mood
Publicité
Posté le 09-01-2008 à 17:31:31  profilanswer
 

n°1668530
Takahani
Posté le 09-01-2008 à 18:06:44  profilanswer
 

Il n'en veux pas de la méthode abstraite, il n'est tjrs pas d'accord d'avoir un type de retour différent entre la méthode abstraite et les méthodes filles. Ce n'est pas grave, je vais revoir la conception de mon programme.
Merci de ta patience !

n°1668532
Taz
bisounours-codeur
Posté le 09-01-2008 à 18:07:53  profilanswer
 

ça peut pas marcher ces virtual avec des types de retours différents

n°1668533
Takahani
Posté le 09-01-2008 à 18:09:19  profilanswer
 

Tout le pb est là finalement :D

n°1668539
Taz
bisounours-codeur
Posté le 09-01-2008 à 18:19:09  profilanswer
 

pourquoi personne veut du variant ?

n°1668543
Takahani
Posté le 09-01-2008 à 18:25:33  profilanswer
 

Variant vient avec la plateforme de dev microsoft, non ?
Le programme doit être cross-plateforme

n°1668546
Joel F
Real men use unique_ptr
Posté le 09-01-2008 à 18:42:12  profilanswer
 

variant ca vien de BOOST :o
www.boost.org

n°1668548
Takahani
Posté le 09-01-2008 à 18:44:29  profilanswer
 

Ok, pkoi pas alors, mais il faut inclure tout boost dans le projet alors ...
C'est pas trop relou à compiler sou wind**be ?
 
Je vais me renseigner. Tjrs un grand merci !
 

n°1668560
Joel F
Real men use unique_ptr
Posté le 09-01-2008 à 19:19:41  profilanswer
 

c'ets uen bibliothèque de .h ... ca se compile guère. En outre, y a deja le binaire win32 de fournie

n°1784818
kyntriad
Posté le 10-09-2008 à 01:14:18  profilanswer
 

Tiens à propos de ce problème de variant, vous auriez pas par hasard une idée de solution vaguement élégante sans utiliser boost par hasard ?

 


Message édité par kyntriad le 10-09-2008 à 01:15:35

---------------
You can't start a fire with moonlight
n°1784833
Joel F
Real men use unique_ptr
Posté le 10-09-2008 à 08:33:41  profilanswer
 

bah non vu que boost implante la version élégante :E
si c'est des prb de lourdeur d'include, regarde du coté de boost bcp pour extraire la partie strictement nécessaire.

 

Mais bon, commencez à vous habituez à ça, boost c'est l'antichambre de std ;)


Message édité par Joel F le 10-09-2008 à 08:34:32
n°1784886
kyntriad
Posté le 10-09-2008 à 10:49:02  profilanswer
 

Joel F a écrit :

bah non vu que boost implante la version élégante :E
si c'est des prb de lourdeur d'include, regarde du coté de boost bcp pour extraire la partie strictement nécessaire.

 

Mais bon, commencez à vous habituez à ça, boost c'est l'antichambre de std ;)

 

Ben à vrai dire j'aimerai beaucoup pouvoir bosser avec sur ce coup-là mais en l'occurrence ça risque d'être foutrement compliqué de faire accepter aux chef d'inclure boost au projet.


Message édité par kyntriad le 10-09-2008 à 10:49:12

---------------
You can't start a fire with moonlight
n°1784889
Joel F
Real men use unique_ptr
Posté le 10-09-2008 à 10:52:40  profilanswer
 

v_v foutu daycidorz >_>
ils utilisent pas la STL aussi :o

n°1784909
kyntriad
Posté le 10-09-2008 à 11:26:10  profilanswer
 

Joel F a écrit :

v_v foutu daycidorz >_>
ils utilisent pas la STL aussi :o

 

Bon j'ai lancé la machine administrative pour savoir si je peux ou pas :o

 


Message édité par kyntriad le 10-09-2008 à 11:26:44

---------------
You can't start a fire with moonlight
n°1784919
Joel F
Real men use unique_ptr
Posté le 10-09-2008 à 11:33:59  profilanswer
 

bon courage :D

mood
Publicité
Posté le   profilanswer
 


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

  Methode template intelligente

 

Sujets relatifs
Class template et membre staticFormulaire/méthode GET et action [résolu]
Passer un nom de méthode et ses paramètres en argumentProblème avec héritage et méthode virtuelle
Pblm héritage et méthode "sans" argument...pb "return" méthode java
Probleme de methodeenvoyer un fichier en methode POST
La solution PHP+XML+XSL=Template est-elle viable ? 
Plus de sujets relatifs à : Methode template intelligente


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