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 :

Template et polymorphisme


Sujet :

Langage C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 6
    Points : 1
    Points
    1
    Par défaut Template et polymorphisme
    Bonjour
    J'ai créé une classe patron CMatrice genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<class T> CMatrice
    {...}
    On peut donc faire des matrices de int ou de double.
    Maintenant, j'ai une autre classe qui contient une matrice genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class CCalcul
    {
    private:
      CMatrice Mat;
    }
    Le problème, c'est qu'il faut que je spécifie le type de matrice (int, double ou n'importe quoi d'autre...). Or je voudrais avoir un objet indépendant dont je spécifie le type lors de l'initialisation et pouvoir utiliser ma matrice sans savoir si c'est une matrice de double ou d'entier. En utilisant les polymorphismes, c'est facile. Mais la, je vois pas comment faire.
    Le solution est peut-être évidente, mais je n'arrive pas a voir comment faire.
    J'espère que je suis clair et que vous pourrez me donner des conseils
    Merci

  2. #2
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut

    transforme CCalcul en classe template
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<typename t>
    class CCalcul
    {
    private:
      CMatrice<T> Mat;
    }
    Mais on peut se demander la pertinence d'une classe pour des algorithmes. Tu l'utilises comment CCalcul ?

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    En fait, j'ai une liste d'algos qui sont regroupés dans des classes en fonction de leur type.
    Parfois, on a besoin de précision, alors on utilise des matrices de double
    Parfois, on a besoin de place en mémoire (les matrices peuvent utiliser plusieurs centaines de Mo) alors on utilise des char.
    Mon objetcif est double: ne pas écrire une classe CMatrice pour chaque type de données et que le type de la matrice soit invisible pour les classes de calcul.
    Il me faudrait donc un objet "Matrice" qui soit initialisé en fonction du type de données (int, double...) et qui puisse être utilisé tel quel par les classes de calculs.
    La solution de passer la classe CCalcul en template fonctionne mais elle suppose de passer toute les classes de calcul en template, ce qui ne rempli pas mon 2eme objectif (Trop contraignant et trop long a faire compte tenu du nombre de classes)
    J'espère que je suis suffisament claire.
    Merci.

    Ps: désolé pour les balises, je débute dans le forum

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Je cerne mal le problème du passage en template.
    Peux tu donner des exemples d'algo de ta classe (prototypes des fonctions) ?

  5. #5
    Membre éprouvé Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Points : 1 122
    Points
    1 122
    Par défaut
    Pour remplir ton objectif, tu dois avoir un pointeur sur la classe CMatrice, ainsi tu construis son type exact à l'exécution de la classe CCalcul.

    Tu peux alors te baser sur le polymorphisme.

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Oui, j'y ai réfléchi, et je crois que c'est la solution. Voici grosso-modo le code obtenu si ca interresse quelqu'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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    class CObj  // classe mère
    {
    ...
    }
     
    template<class T>
    class CMatrice: public CObj // class fille pour les entiers
    {
    private:
      T* m_pData;
      int m_Lig, m_Col;
    public:
      CMatrice();
      ~CMatrice();
     
      Init(int lig, int col, TVal);
    ...
    }
     
    class CCalcul
    {
    private:
      CObj* m_pMat; // Pointeur sur la class mère
     public:
      CCalcul (CObj* pMatrice) {m_pMat=pMatrice}
      ~CCalcul();
     
      FFT2D(); // Calcul la FFT 2D de m_pMat
    }
     
    main()
    {
      CMatrice<unsigned char> Mat;
      CCalcul Calcul(&Mat);
      Calcul.FFT2D();
    }
    On se contente de choisir le type des données dans le même. Tout le reste marche presque tout seul.
    Merci pour vos reponses

  7. #7
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class CCalcul 
    { 
    private: 
      CObj* m_pMat; // Pointeur sur la class mère 
     public: 
      CCalcul (CObj* pMatrice) {m_pMat=pMatrice} 
      ~CCalcul(); 
     
      FFT2D(); // Calcul la FFT 2D de m_pMat 
    }
    Comment FFT2D peut-il connaître le type des données à traiter char, unsigned char, int, float,.... ?
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  8. #8
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    En quoi ta classe CCalcul est plus justifiée que des fonctions libres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    namespace Calcul
    {
        template<typename T>
        void FFT2D( CMatrice<T> & Mat );
    }
     
    int main() 
    { 
      CMatrice<unsigned char> Mat; 
      Calcul::FFT2D( Mat ); 
    }
    ?

    Sinon, en procédant ainsi avec ta classe CObj tu va à l'encontre du principe des template. Si tu utilises les templates, utilise les jusqu'au bout

  9. #9
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Je ne doit pas m'exprimer très clairement, j'en suis désolé.
    Le placement des fonctions dans des classes m'est imposé. C'est la norme choisit dans ce projet. Pas de fonction libre, tout doit être dans des classes. De plus, certaines classe peuvent contenir des données membres à mémoriser qui sont utilisé par d'autres fonctions...
    Il est vrai qu'en utilisant la classe CObj, je ne vais pas jusqu'au bout des templates. Mais il ya de nombreuses classe de calcul, et de nombreuses fonction dans chaque classe. Impossible de tout modifier pour tout passer en template!!!
    Certe, une fonction comme FFT2D ne peut plus savoir quelle est le type des données. Mais en fait, on a pas tout le temps besoins de savoir quel est le type des données. Je prend un exemple + simple. J'ai une fonction qui fait la somme de toute les valeurs de la matrice. Dans cette fonction, peu importe de savoir quelle est le type de données, on demande juste d'en faire la somme.
    Mais il est fort possible que je me prenne bien la tête pour rien et qu'il y ai une solution fort simple que je ne vois pas...

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    J'ai une fonction qui fait la somme de toute les valeurs de la matrice. Dans cette fonction, peu importe de savoir quelle est le type de données, on demande juste d'en faire la somme
    Biensûr que tu as besoin de connaître le type. Faire la somme d'un tableau de double ou d'un tableau de char, c'est pas le même code derrière.

  11. #11
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Si on peut:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int i,j;
    double Sum=0;
    for (i=0;i<Mat.lig();i++)
      for (j=0;j<Mat.col();j++)
         Sum+=Mat[i][j];
    Il est vrai que ca oblige a bien choisir les variables intermédaires (ie le "double Sum"). Mais de toute façon, pour éviter les dépassement, c'est presque obligé de prendre un double (ou en tout cas un type de capacité supérieur).
    Je reconnais néanmoins que dans certain cas, ca pourrais être utile de connaitre le type des données. En fait, mon objectif est de faire un code ou l'utilisateur des classes ne se pose pas trop de question sur le type de données. Il dit que c'est des "int" ou des "double" et ca marche tout seul. Mais comme j'ai des problèmes avec mon "CObj", tout passer en template est peut-être la seul solution bien que passer le projet entier en template ne me semble pas vraimement faisable.
    Bon je vais continuer d'y reflechir. Merci beaucoup

  12. #12
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Pierre_IPROS
    Si on peut:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int i,j;
    double Sum=0;
    for (i=0;i<Mat.lig();i++)
      for (j=0;j<Mat.col();j++)
         Sum+=Mat[i][j];
    Je te rappelle que dans ton cas Mat est un CObj. Peux-tu donner le code des opérateurs [] de CObj ?
    On ne peux pas faire ce que tu veux.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    char tab1[ 10 ];
    for (int i = 0; i < 10; ++i )
    {
        double d = tab1[ i ];
    }
    double tab2[ 10 ];
    for (int i = 0; i < 10; ++i )
    {
        double d = tab2[ i ];
    }
    dans le premier cas, la mémoire pointée par tab1 va être parcourue octet par octet. Dans le second, celle pointée par tab2 le sera à coup de 8 octets. C'est là qu'est le problème : sizeof( char ) != sizeof( double ).
    Les templates sont la solution. Le compilo génère autant de version que nécessaire.

  13. #13
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Lors de la construction de CCalcul, tu transtype le pointeur sur Mat en CObj*. Pour accéder, suivant ce code aux éléments de m_pData dans CMatrice, tu as surchargé (2 fois) avec des méthodes virtuelles l'opérateur [] ?
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  14. #14
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Pas possible, déjà parce qu'un opérateur ne peut pas être virtuel, mais surtout parce que les méthodes virtuelles doivent avoir la même signature (hors retour covariant, c'est pas le cas ici), or là un coup il faut renvoyer un char, un coup un double, un autre un X...

  15. #15
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Effectivement, je suis d'accord avec vous que ya des problèmes.

    Mais utiliser simplement des templates, ca ne regle pas tous mes problemes. Par exemple, si je vaux stocker des matrices de différent type dans une classe, celui-ci doit passer en template avec autant d'argument que j'ai de matrices. Pour afficher mes matrices, la vue doit être en template... Tout ca devient vite ingérable, a moins que je sois passer a côté d'une idée très simple...
    Et si je veux faire un tableau avec des matrices de type différents, quelles solutions voyez-vous? C'est très facile en polymorphisme, il suffit de stocker un objet de la classe mère mais avec des templates, je sais pas faire... Peut-être que je demande l'impossible: avoir les avantages du polymorphisme et des templates...

  16. #16
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Faudrait décrire un peu + l'utilisation que tu fais de la matrice (rôle du tableau, type de vue...).

  17. #17
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Comme ton problème est rigolo, j'y ai un peu réfléchi en mélangeant template et polymorphisme. Je suis arrivé à une solution imparfaite :
    Une classe de base abstraite pour les données. (Round est une fonction permettant de faire les arrondis ou de gérer les overflow en fonction du type des données, on peut s'en passer éventuellement)
    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
    class Data
    {
      virtual double GetData()=0;
      virtual void SetData (double valeur)=0;
      virtual double Round(double valeur)=0 ;
    public :
      int Col;
      int Lgn;
      operator double()
             {return GetData();}
      Data & operator = (Data & ln)
             {assert  (ln != *this); SetData (ln.GetData());return *this; }
      Data & operator = (double valeur)
             { SetData (valeur);return *this;}
    } ;
    une classe données template
    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
    template <class T>
    class DataT : public Data
    {
    private :
       T * data;
       int Dim ;
       double GetData()
              {return data[Lgn*Dim+Col] ;}
       void SetData (double valeur)
              {data[Lgn*Dim+Col]= Round(valeur);}
       double Round(double valeur);
    public :
       DataT(T* tableau, int dim):data(tableau),Dim(dim){}
    };
    template <>
    double DataT< int>::Round(double valeur)
           {return valeur >0 ? floor(valeur+0.5):ceil(valeur-0.5);}
    template <class T>
    double DataT< T>::Round(double valeur)
           {return valeur;}
    Une classe pour représenter le tableau et gérer les indices
    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
    class Tab2D
    {
    private :
      class Lignes
      {
       friend class Tab2D ;
       private :
        Data * tab;
        Lignes(Data* data):tab(data){ }
       public :
        Data & operator[](int col)
               {tab->Col = col; return *tab; }
      }t;
    public :
      Lignes & operator[](int lgn)
               { t.tab->Lgn = lgn;return t;}
      Tab2D  & operator ()(int lgn, int col)
               { t.tab->Lgn = lgn ; t.tab->Col=col; return *this;}
      Tab2D  & operator = (double valeur)
               { *(t.tab) = valeur; return *this; }
      Tab2D  & operator = (Tab2D & ln)
               {assert(ln != *this);*(t.tab) = *(ln.t.tab);return *this;}
               operator double()
               { return *(t.tab);}
      Tab2D(Data* data):t(data){}
     };
    La surcharge de l'opérateur() permet une écriture Tab(1,1) au lieu de Tab[1][1] et est plus légère à gérer par la classe. On aboutit à des appels du style :
    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
     
    void calcul(Tab2D tab,int n, int m)
    {
       for(int i=0; i<n-1;i++)
        for(int j=0;j<m-1;j++)
          tab[i][j] = tab[i][j] +tab[i+1][j+1];
    }
    //----------------------------
    void init(Tab2D tab,int n, int m)
    {
       for(int i=0; i<n;i++)
        for(int j=0;j<m;j++)
          tab[i][j] = 10*i+j*1.1;
    }
    //----------------------------
    void print(Tab2D tab,int n, int m)
    {
       for(int i=0; i<n;i++)
          for(int j=0;j<m;j++)
             std::cout<< i<<"  " <<j<<"  "<< (double)tab[i][j]<<std::endl;
       std::cout<<std::endl;
    }
    //----------------------------
    ...
     int ti[4][5];
     float tf[2][3] ;
     DataT<int> tbi( (int*)ti, 5);
     Tab2D tabi(&tbi);
     DataT<float> tbf( (float*)tf, 3);
     Tab2D tabf(&tbf);
     
     tabi[1][2] = 3 ;
     float f = tabi[1][2];
     tabf[0][1] = 0.4416;
     f = tabf[0][1] ;
     tabf[1][1] = tabi[0][1] ; //OK
    //  tabf[1][1] = tabf[0][1] ;//erreur 
     tabf[1][1] = (double) tabf[0][1] ;//OK
     
     init(tabi,4,5);
     calcul(tabi,4,5);
     print(tabi,4,5);
     init(tabf,2,3);
     calcul(tabf,2,3);
     print(tabf,2,3);
     
     tabf(0,2)=1.2345;
    // tabf(1,2) = tabf(0,2) ; //erreur
     
     Tab2D tab[2] = {tabi,tabf};
     tab[0][1][1] = tab[1][1][1]+ 2*tab[0][2][2]+2.5;
    Le problème est que ceci ne gère pas les expressions du genre tabf[1][1] = tabf[0][1] où à droite figure uniquement le même tableau qu'à gauche au lieu d'une expression et il faut transtyper(voir listing ci-dessus). Si quelqu'un a une solution ....
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  18. #18
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Si tu dois stocker tes matrices, il est peu probable que dans un même container tu en stockes qui soient de type différents.
    J'ai plutôt l'impression que tu doives réécrire (cf Blitz++, boost.uBlas, ...) des bibliothèques mathématiques matricielles.
    Il est naturel de prévoir plusieurs types de matrices (très facilement résolu avec des templates), mais il est improbable de devoir mélanger des matrices de types différents.

    De fait une solution 100% template suffit.

    Si des mélanges sont à envisager, il faut voir quels sont les rôles communs qui peuvent être isolés et pour lesquels on veut du polymorphisme d'inclusion.
    Isole les dans des contrats et fais-en dériver tes matrices.
    Mais souviens toi que des matrices sont cencées disposer d'une sémantique de valeur et que donc introduire un héritage va introduire des complications qui vont se résoudre par l'idiome enveloppe-lettre.

    Avec des mixin-layers, il est aussi possible d'avoir des bibliothèques plus "flexibles". Par exemple, j'avais pensé, pour une bibliothèques pour réseaux de neurones artificiels, à disposer de types RdN de base qui soient disjoints (ce qui est tout à fait logique avec le fait que chaque type de RdN est assez unique). Mais par moment, il faut pouvoir les manipuler ensemble, ou de façon polymorphique dont la résolution ne pourra être que dynamique.
    Notament, s'il faut disposer d'un composant qui permet de créer et manipuler des RdN dont on spécifie le type non plus à la compilation, mais à l'exécution.
    Avec des mixin-layers, il est possible de spécifier comme type (template) dont on dérive un classe qui soit soit vide (=> tous les RdNs ne sont pas cousins) ou alors une interface/contrat (=> divers RdN descendront d'un parent commun).
    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
    template <typename T, class Super>
    struct M : Super
    { void f() {...} ; };
     
    struct None {} ;
    struct If
    { virtual f() = 0; };
    ...
    M<int, None> mi;
    M<char, None> mc;
    // mi et mc sont indépendants de toute chose
     
    M<double, If> mf;
    M<Polynome, If> mp;
    If * m = mf;
    m = mp; // mf et mp "sont-des" If.
    (Note: une matrice peut très bien être une matrice de polynomes, et un polynome ne tient pas dans un double.) Suivant le type d'application, on choisit dans chque projet ce que l'on veut vraiment.

    Dans le même genre, il est possible d'avoir une hiérarchie d'enveloppes templates.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct E : boost::non_copyable {
       virtual f() = 0;
    };
     
    template <typename T> struct Eimpl : E
    {
        virtual f() { m.f() ; }
    private:
        M<T> m;
    };
    Note: Rien de ceci ne marchera si f doit prendre un T en paramètre.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  19. #19
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    C'est dommage que tes classes de calcul ne soient pas tes classes matricielles, ça serait plus logique, le calcul s'effectuant sur tes matrices, les méthodes devraient être dans la classe matricielle. C'est ce que j'ai fait pour ma classe matricielle, 1 classe pour les matrices, entièrement templatisée, tous les opérateurs sont dans la classe.
    Sinon, il te faut templatiser ta classe de calcul aussi.

  20. #20
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Ben non. Les opérateurs doivent être sortis.
    Et sortir les algos des données n'est pas illogique. C'est déjà ce qui se passe en parti dans la SL. Et dans les poids des bibliothèques matricielles en C++.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. probleme template et polymorphisme
    Par thenewby dans le forum Langage
    Réponses: 9
    Dernier message: 16/07/2012, 16h48
  2. templates et polymorphisme
    Par mister3957 dans le forum C++
    Réponses: 9
    Dernier message: 01/04/2009, 16h59
  3. Template et Polymorphisme = contrainte ?
    Par poukill dans le forum Langage
    Réponses: 29
    Dernier message: 06/02/2008, 20h27
  4. template et polymorphisme
    Par new.proger dans le forum Langage
    Réponses: 14
    Dernier message: 28/08/2007, 00h35
  5. Template et polymorphisme
    Par fabienpot dans le forum Langage
    Réponses: 9
    Dernier message: 07/09/2006, 16h32

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