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

C++ Discussion :

Classe template générique


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par défaut Classe template générique
    Bonjour à tous,

    J'ai encore quelques difficultés (si ce n'est beaucoup ) à comprendre les templates. Est-il possible, via ces derniers de créer une classe générique comme cela (la représentation est bien sur grossiè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
    class A
    {
    template<typename U, typename V>map<U,V> list;
     
    template<typename U, typename V> void Add_Data(U key, V value) 
    { 
        list.insert(pair<U,V>(key,value));
    }
     
    template<typename U, typename V> V Get_Data(U key) 
    {
     return *(list.find(key));
    }
    }
    merci d'avance

  2. #2
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    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
    template<typename U, typename V>
    class A
    {
    map<U,V> list;
     
    void Add_Data(U key, V value) 
    { 
    list.insert(pair<U,V>(key,value));
    }
     
    V Get_Data(U key) 
    {
    return *(list.find(key));
    }
    }
    est la bonne maniere

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par défaut
    Merci pour la rapidité de la réponse Joel !

    C'était à peu près ce que j'avais compris de l'histoire, je suis pas si nul que ca en fin de compte .
    Cependant, cela implique une autre problématique car pour utiliser cette classe A avec toutes les combinaisons de types <U,V>, il m'est nécessaire de devoir définir une nouvelle variable à chaque fois, ce qui est embêtant. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class B
    {
    private:
        A<bool,int> t1;
        A<string,bool> t2;// etc etc
     
    }
    Ce qui devient lourds si on doit gérer toutes les combinaisons.

    N'y-t-il pas un moyen de gérer ca avec une seule variable ? J'ai cru comprendre que boost::variant était une solution...

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il faut faire attention au fait que, lorsque tu crées une classe template et qu'elle n'hérite pas d'une classe de base qui ne serait pas template, une instance de type TaClass<A, B> n'a strictement rient à voire (hormis l'interface et le comportement) avec une instance de type TaClass<C, D>, ni même seulement avec une instance de type TaClass<A, C>...

    Ce que je veux dire par là, c'est que tu ne pourras absolument pas envisager de créer une collection d'objets qui contiendrait une instance de TaClass<A, B> et une instance de TaClass<C, D> .

    Le but des template est d'autoriser l'utilisation du paradigme dit "générique", c'est à dire un moyen qui te permettra d'écrire peu de code, mais de le faire s'adapter à de nombreuses situations quant aux types utilisés, pour autant que les types en question respectent une interface donnée.

    Si le but est, comme ta question semble le suggérer, de pouvoir profiter de la substituabilité des différents types, il faudra de toutes manière en arriver à avoir une classe de base commune, avec l'héritage qui va bien...
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par défaut
    Au risque de paraitre têtu (désolé par avance koala01), j'ai essayé quelque chose. Ca en marche pas bien sur, sinon ca aurait été trop facile. Je veux juste saisir ce concept de template.

    Le Point.h
    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
     
    typedef boost::variant<int ,double> IType;
     
    class Point : public Coords
    {
    private:
        Datas<unsigned int,IType > idata;
    public:
        Point(const double _x, const double _y, const double _z);
        virtual ~Point(){}
        virtual string __ToString(const bool _parent=false) const;
        template<typename T> bool AddData(const unsigned int tag, const T t);
        template<typename T> const T &GetData(const unsigned int tag) const;
     
    };
    Le Point.cpp :
    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
    Point::Point(const double _x, const double _y, const double _z):Coords(_x,_y,_z)
    {
    }
     
        string Point::__ToString(const bool _parent) const
        {
        ostringstream oss;
        if (!_parent) oss << "########## COORDS ##########"<<endl;
        oss.precision(4);
        oss << "("<<_x()<<";"<<_y()<<";"<<_z()<<")"<<endl;
        return oss.str();
        }
       template<typename T> bool Point::AddData(const unsigned int tag, const T t)
     
        { idata.Add_Data(tag,t); return true;}
     
        template<typename T> const T & Point::GetData(const unsigned int tag) const
        {
    	idata.Get_Data(tag);
        }
    Le datas.h
    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
     
    #include <map>
    using namespace std;
    template<typename U, typename V>class Datas
    {
    private:
        map<U,V> list;
    public:
        Datas(){}
        void Add_Data(U key, V value)
        {
        list.insert(pair<U,V>(key,value));
        }
     
        V Get_Data(U key)
        {
        return *(list.find(key));
        }
     
        void Remove_Data(U key)
        {
    	list.erase(list.find(key));
        }
    };
    et le main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int main(){
        Point c(1,2,3);
        c.AddData(3, 2.1);
    }

    Pourquoi il me sort ca lors de la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Undefined symbols:
      "bool ICMole::Point::AddData<double>(unsigned int, double)", referenced from:
          _main in main.o
    ...

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,

    Citation Envoyé par gilims Voir le message
    Pourquoi il me sort ca lors de la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Undefined symbols:
      "bool ICMole::Point::AddData<double>(unsigned int, double)", referenced from:
          _main in main.o
    ...
    F.A.Q. : Pourquoi mes templates ne sont-ils pas reconnus à l'édition des liens ? . C'est aussi vrai pour les fonctions membres template d'une classe non template.


    Au passage :
    __ToString : Quels sont les identificateurs interdits par la norme ?

    Pas de using namespace dans un fichier d'en-tête F.A.Q: Quand utiliser / ne pas utiliser using namespace ?

    virtual string __ToString c'est très bof (ça sent le java à plein nez) La sérialisation en chaîne je n'aime pas trop l'avoir dans la classe. En plus ça sent la fonction d'un SuperObject duquel vont dériver tout tes objets. Bref, pas terrible d'un point de vue design

    class Point : public Coords J'ai du mal avec ça. A priori, Point (et Coords) ont une sémantique de valeur et non d'entité incompatible avec de l'héritage. Respectes-tu bien le LSP (héritage EST-UN) ? Ou les classes sont mal nommées ou le design est hasardeux.

    L'héritage se marie mal avec la copie. J'espère que Coords interdit la copie

    J'aurais mis typedef boost::variant<int ,double> IType; dans la classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    class Point : public Coords
    {
    typedef boost::variant<int ,double> IType;

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur .NET/C/C++
    Inscrit en
    Septembre 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET/C/C++
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2007
    Messages : 71
    Par défaut
    Plusieurs remarques:
    - Pour ta classe Data, je ne vois pas trop à quoi elle sert. Pour moi, tu peux utiliser une std::map directement.
    -
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Undefined symbols:
      "bool ICMole::Point::AddData<double>(unsigned int, double)", referenced from:
          _main in main.o
    Pour info, ce n'est pas un problème à la compilation mais bien à l'édition de liens. C'est une erreur classique quand on apprend à utiliser les templates (je l'ai faite avant toi ) Voir la faq pour plus d'infos.

    (EDIT : grilled )

    - Ta variable idata va contenir des valeurs qui seront soit des entiers, soit des doubles, chaque valeur étant indéxée via un entier non signé. Est-ce bien là ce que tu veux faire?

    - Pour ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    12345678  
    class B
    {
    private:
        A<bool,int> t1;
        A<string,bool> t2;// etc etc
     
    }
    ce qu'il faut que tu comprennes, c'est que
    représente un type, et
    représente un autre type.
    Du coup, tes variables t1 et t2 sont bien de type différent, donc impossible de les stocker directement dans une même variable. L'utilisation de boost::variant peut effectivement aider, encore faut-il voir s'il s'agit bien de la solution la plus adaptée à ton problème.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Classe Liste générique avec template
    Par TNT89 dans le forum Langage
    Réponses: 9
    Dernier message: 09/05/2009, 15h14
  2. [DLL/classe template] problème de link
    Par Bob.Killer dans le forum C++
    Réponses: 7
    Dernier message: 31/08/2005, 18h56
  3. Class template hérité
    Par Azharis dans le forum Langage
    Réponses: 4
    Dernier message: 24/06/2005, 22h03
  4. Réponses: 6
    Dernier message: 06/10/2004, 12h59
  5. classe date générique ?
    Par lili_bzh dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 07/09/2004, 10h59

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