IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Méthode template intelligente


Sujet :

Langage C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 3
    Par défaut Méthode template intelligente
    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 )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    // en réalité ces définitions sont ailleurs, je les rajoute ici pour compréhension
    #define VTK_DOUBLE 1
    #define VTK_FLOAT 2
    #define VTK_INT 3
     
    class MaClasseA
    {
        MaClasseA(void );
        template <typename T> T GetData(const int index);
        void *ptr;
        int type;
    }
     
    void MaClasseA::MaClasseA(void)
    {
    // 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. 
    // Le souci est que je ne peux pas savoir à l'avance de quel type seront les données, cela dépend des images. 
    // 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.
        ptr=ImageData->GetDataPointer(); 
     
        // renvoi VTK_DOUBLE ou VTK_FLOAT ou autres
        type=ImageData->GetScalarType();
    }
     
    template <typename T> T MaClasseA::GetData(const int index)
    {
       switch (type)
       {
            case VTK_DOUBLE :
                return static_cast<double *>(ptr)[index];
                break;
     
            case VTK_FLOAT :
                return static_cast<float *>(ptr)[index];
                break;
     
            default :
                break;
        }
    }
     
    class MaClasseB : public MaClasseA
    {
        MaClasseB();
        void MaMethodeAuPif(void);
    }
     
    void MaClasseB::MaClasseB(void){;}
    void MaClasseB::MaMethodeAuPif(void)
    {
        cout<<"Valeur du voxel 150 "<<GetData(50)<<endl;
    }
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    void MaClasseB::MaMethodeAuPif(void)
    {
        switch (InstanceClasseA->GetType())
       {
            case VTK_DOUBLE :
                cout<<"Valeur du voxel 150 "<<GetData<double>(50)<<endl;
                break;
     
            case VTK_FLOAT :
                cout<<"Valeur du voxel 150 "<<GetData<float>(50)<<endl;
                break;
     
            default :
                break;
        }
    }
    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 MaMethodeAuPif dans différentes classes qui héritent de MaClasseA, et je voudrais éviter le switch avec les 15 types à chaque fois ...

    La solution du pb ne doit pas être très loin de cette section de la FAQ C++, mais je ne vois pas comment faire.
    http://cpp.developpez.com/faq/cpp/?p...TES_parametres

    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

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Bonjour et bienvenue sur le forum.
    Les templates sont interprétées pendant la compilation.
    Donc si le type est connu pendant la compilation ça doit être possible sinon non.
    Ne serait il pas plus correcte que ce soit ta class qui soit template??

  3. #3
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    A mon avis, c'est ta classe qui devrait etre template, et tu devrais instancier une classe pour chaque image récupérée.

  4. #4
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Dans tous les cas, les templates ne feront pas le boulot à ta place si ça se décide à l'exécution.

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Tu veux peut-être quelque chose dans le genre de boost.variant ou boost.any ?

  6. #6
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Evidemment ce qu'il veut faire n'est pas envisageable.
    Mais je pense que le type de données est lié à l'image et qu'il ne change pas durant toute la vie de celle-ci.
    S'il instancie une classe par image, il peut sauver le type de données en tant que parametre template (ou seulement le numéro VK via un parametre template non type et il retrouve le bon type par une classe de trait).

    Ensuite il peut se servir d'une fonction à polymorphisme statique pour l'affichage afin d'éviter les redondances.

  7. #7
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Si la nature de l'image de change pas, c'est tout a fait jouable oui.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut
    et avec type_info?

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Le type de retour doit être déterminé à la compilation. Si on détermine le type pendant l'execution cela ne servira pas.

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    A mon avis, c'est ta classe qui devrait etre template, et tu devrais instancier une classe pour chaque image récupérée.
    +1
    Cela va surtout dépendre de ta vision des choses. Peut être les deux te correspondrais?
    • template : code indépendant du type de l'image ou autre et reutilisable
    • polymorphisme : utilisation dynamique pendant l'exécution grâce à une interface bien pensée et suffisante


    Mais y aura toujours un switch ou autre quelque part

  11. #11
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par reptils Voir le message
    et avec type_info?
    Il me semble que les implémentations de type_info non sont pas trés bonne suivant les compilateurs et qu'il faut mieux ne pas trop l'utiliser.

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 3
    Par défaut
    Bonjour merci pour vos réponses !

    Je suis parti vers une solution avec du polymorphisme mais je ne m'en sors toujours pas
    Dès 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'entends pas là 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
     
       class AccessData{
       protected:
           void* pData;
       public:
           AccessData(void* data) {pData=data; }
           virtual void GetData(int x, ...);
       };
     
       class Access_Char : public AccessData {
       public:
          Access_Char(void* data):AccessData(data){;}
          virtual char GetData(int x){return static_cast<char*>(pData)[x];}
      };
     
      class Access_Unsigned_Char : public AccessData {
      public:
          Access_Unsigned_Char(void* data):AccessData(data){;}
          virtual uchar GetData(int x){return static_cast<uchar*>(pData)[x];}
      };
    Puis dans une autre classe, j'aurai un pointeur vers AccessData

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       AccessData *pData;
    Et au moment du chargement des l'images, je pourrai alors faire un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
       int nDataInType=ImageDataInput->GetScalarType();
           switch (nDataInType)
           {
              case VTK_CHAR :
                   pDataIn=new Access_Char(pDataInput);
                   break;
     
              case VTK_UNSIGNED_CHAR :
                   pDataIn=new Access_Unsigned_Char(pDataInput);
                   break;
     
              case VTK_SHORT :
                   pDataIn=new Access_Short(pDataInput);
                   break;   
           }
    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

  13. #13
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Ça tu ne peut pas le faire....
    Tu ne peut pas avoir un retour différent de la fonction hérité.
    La où les templates serait peut être meilleur dans ton problème sera que tout le code ne dépendra pas du type de l'image. A part les spécialisations que tu fera.
    C'est difficile de te repondre, ce n'est pas trés claire ton problème. Tu as peut être un problème de conception.
    Si tu as un diagram UML, cela pourrai peut être aider.

  14. #14
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 3
    Par défaut
    Bonjour, oui je suis nul en conception, du coup j'arrive à un gros truc qui fait n'importe quoi.
    Et comme tu peux l'imaginer, je n'ai pas fait de diagramme UML

    Bon c'est pas grave, je vais essayer de me débrouiller autrement. Merci pour tout en tout cas !
    Simon

  15. #15
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Tu veux peut-être quelque chose dans le genre de boost.variant ou boost.any ?
    as tu regardé ca?

  16. #16
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 4
    Par défaut
    Voilà peut-etre que ça peut t'aider
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    typedef enum
    {
       VTK_DOUBLE= 1,
       VTK_FLOAT,
       VTK_INT
    } tType;
     
    class Data
    {
    public:
       virtual ~Data()
       {
       }
     
       virtual Data &operator(int idx) = 0;
       virtual void print(ostream &o) = 0;
    };
     
    template<typename T>
    class TypedData : public Data
    {
       T *base;
       int i;
     
    public:
       TypedData(void *b)
       : base((T *)b), i(0)
       {
       }
     
       Data &operator()(int idx)
       {
          i= idx;
     
          return *this;
       }
     
       void print(ostream &o)
       {
          o << base[i];
       }
    };
     
    ostream &operator<<(ostream &o, const Data &d)
    {
       d.print(o);
     
       return o;
    }
     
    class MaClasseA
    {
        MaClasseA(void );
        Data &GetData();
        Data &GetData(int i);
        void *ptr;
        tType type;
    }
     
     
    void MaClasseA::MaClasseA(void)
    {
    // 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. 
    // Le souci est que je ne peux pas savoir à l'avance de quel type seront les données, cela dépend des images. 
    // 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.
        ptr=ImageData->GetDataPointer(); 
     
        // renvoi VTK_DOUBLE ou VTK_FLOAT ou autres
        type=ImageData->GetScalarType();
    }
     
    Data &MaClasseA::GetData()
    {
       switch (type)
       {
            case VTK_DOUBLE :
                return *new TypedData<double>(ptr);
                break;
     
            case VTK_FLOAT :
                return *new TypedData<float>(ptr);
                break;
     
            default :
                break;
        }
    }
     
    Data &MaClasseA::GetData(int i)
    {
       return GetData()(i);
    }
     
     
    class MaClasseB : public MaClasseA
    {
        MaClasseB();
        void MaMethodeAuPif(void);
    }
     
    void MaClasseB::MaClasseB(void){;}
    void MaClasseB::MaMethodeAuPif(void)
    {
        cout<<"Valeur du voxel 150 "<<GetData(50)<<endl;
        cout<<"Valeur du voxel 160 "<<GetData(60)<<endl;
     
    // ou alors:
       Data &d= GetData();
     
       cout<<"Valeur du voxel 150 "<< d(50) <<endl;
       cout<<"Valeur du voxel 160 "<< d(60) <<endl;
    }
    J'ai pas compilé, mais ca devrait, et l'idée y est.

  17. #17
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 4
    Par défaut
    Pour ton probleme avec ta solution polymorphe, plutot que chercher à avoir des methodes qui retourne des types différents essaie de retourner les valeurs via des paramètres références:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void GetData(int i, char &c);
    void GetData(int i, double &d);
    void GetData(int i, long &l);
    La valeur est retournée via le 2nd paramètre, donc au lieu de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    double d= GetData(50);
    cout << d;
    Tu pourras faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    double d;
    GetData(50,d);
    cout << d;
    mais peut etre que cette solution ne te plairas pas a cause de la variable que tu dois déclarer avant.

  18. #18
    Membre éclairé Avatar de SKone
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 333
    Par défaut
    Je voudrais ajouter un truc même si le type est déterminé à l'éxecution un traitement est possible avec les mécanismes de RTTI (typeid, type_info, dynamique_cast) bien qu'il y est une perte de performance à l'execution et des pertes en temps de compilation mais négligeable par rapport au perte (à la compilation) du au template.

Discussions similaires

  1. Méthode template const
    Par nikopol82 dans le forum Langage
    Réponses: 7
    Dernier message: 17/04/2008, 14h30
  2. Méthode template : déclaration/définition et appel ?
    Par kidpaddle2 dans le forum Langage
    Réponses: 3
    Dernier message: 22/04/2007, 14h09
  3. Méthode template dans classe non template ?
    Par shenron666 dans le forum Langage
    Réponses: 12
    Dernier message: 04/09/2006, 17h50
  4. Appeler une méthode template d'un paramètre template
    Par YéTeeh dans le forum Langage
    Réponses: 2
    Dernier message: 26/08/2006, 12h50
  5. Méthode template virtuelle
    Par ced1 dans le forum Langage
    Réponses: 6
    Dernier message: 13/11/2005, 15h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo