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 :

[C++] Enumeration de classes


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 8
    Par défaut [C++] Enumeration de classes
    Bonjour à tous,

    Je suis face à un petit problème de conception : je cherche à savoir s'il est possible d'énumer des types. Afin d'etre plus clair je vous donne mon code et je vous expose mon problème ensuite.

    Compilateur: GCC
    Environment: Code::Blocks v1


    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
    
    NB: le code de la classe Interf_Register ne pose pas de problème ici: c'est juste une interface classique (je les notes par Interf_X ou X est le nom de la classe a interfacer).
    
    
    template <class INTERF_TYPE , class CONTENEUR_TYPE = std::vector<INTERF_TYPE *> >
    class Register : public Interf_Register, public CONTENEUR_TYPE
    {
    public:
        virtual std::string GetInfo_Summary(void);
    
    public:
        void Add (INTERF_TYPE* ToReg) {push_back(ToReg);}
        int GetSize(void) {return (int) size();}
    };
    
    template <class INTERF_TYPE, class CONTENEUR_TYPE>
    std::string Register<INTERF_TYPE,CONTENEUR_TYPE>::GetInfo_Summary(void)
    {
        std::ostringstream oss;
        oss << "Registre: " << GetName() << " ; Contenu: " << GetSize() << " elements.\n";
        return oss.str();
    }
    
    
    QQ exemples d'application de ma classe précédente:
    
    typedef Register<Interf_Toto> Register_Toto;
    
    typedef Register<Interf_Amination, std::deque<Interf_Amination*> > Register_Animation;
    Le problème réside dans l'appel de la méthode size() contenu dans la methode GetSize() : size() est une méthode générique sur les conteneurs de la stl et le compilateur (gcc) refuse ce code car il dépend d'un template . Je pourrais lever ce problème en mettant le compilateur en mode permissif, mais j'aimerai éviter cela et garder en template le type de conteneur pour pouvoir facilement le changer plus tard (ad hoc).

    En fait, je voudrais restrindre le choix de l'argument template "class CONTENEUR_TYPE" à une liste de conteneurs donnés afin de rendre plus propre ce code et ca je ne sais pas faire... J'aurai besoin de vos suggestions et de votre expérience... SVP!!!

    Peut-on faire une liste de classes à la manière d'une enum (j'y connais presque rien en enum)?



    j'aurais aimé avoir un truc du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    template<class interface>
    enum MesConteneurQuiMArchent
    {
    std::vector<interface>,
    std::deque<interface>,...
    };  
     
    et pour les template de la class Register:
     
    template <class INTERF_TYPE , class MesConteneurQuiMArchent<INTERF_TYPE *> CONTENEUR_TYPE = std::vector<INTERF_TYPE *> >
    ... mais c'est sans doute completement foireux... Auriez vous d'autre idées pour faire restreidre cet argument template?


    En espérant avoir été assez clair, et merci d'avance pour votre aide




    Dalo

  2. #2
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    À moins que je fasse erreur, il me semble que enum sert à faire une collection d'entiers constants donc je ne crois pas que tu peux appliquer celà aux conteneurs de la STL.

    Deuxièment, à moins que je fasse erreur, il fait plus ou moins de sens qu'il y ait un appel à la méthode size() sans rien autour de l'os. (Est-ce que tu sous-entends this->?) Normalement on verrait quelque chose du type monConteneur.size() ou alors sizeof(type). Mais size() simplement?

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Citation Envoyé par Dalo
    je cherche à savoir s'il est possible d'énumer des types.
    C'est possible, regarde les typelists d'Alexandrescu.

    Citation Envoyé par Dalo
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     
    template <class INTERF_TYPE , class CONTENEUR_TYPE = std::vector<INTERF_TYPE *> >
    class Register : public Interf_Register, public CONTENEUR_TYPE
    {
    };
    Ce n'est en general pas une bonne idee de deriver des conteneurs de la SL : ils n'ont pas ete prevus pour ca (notamment, ils n'ont pas de destructeur virtuel).

    Citation Envoyé par Dalo
    Le problème réside dans l'appel de la méthode size() contenu dans la methode GetSize() : size() est une méthode générique sur les conteneurs de la stl et le compilateur (gcc) refuse ce code car il dépend d'un template.
    this->size() devrait resoudre ce probleme. Sinon, tu peux aussi ecrire CONTENEUR_TYPE::size().

    Citation Envoyé par Dalo
    En fait, je voudrais restrindre le choix de l'argument template "class CONTENEUR_TYPE" à une liste de conteneurs donnés
    Ce n'est pas possible avec un enum : un enum cree des litteraux ayant des valeurs entieres, pas des alias sur des types. En utilisant boost, tu peux arriver a une solution en utilisant boost::is_same et BOOST_STATIC_ASSERT.

  4. #4
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Tu te débrouilles pas mal en français pour un américain roulious

  5. #5
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 8
    Par défaut
    Merci beaucoup pour vos réponses.

    Je ne savais pas que deriver des conteneurs de la SL était un mauvais choix; merci pour cette précision roulious.

    Pour mon code je pense que je vais quand meme garder cette dérivation des conteneurs car mes classes filles sont juste des conteneurs avec quelques petites methodes de traitement (vraiment rien de méchant).

    Encore merci pour tes explications roulious.

    Dalo

  6. #6
    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
    Par contre, l'une des solutions qui *pourrait* convenir, serait de créer une énumération sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    enum TYPENAME{TYPE1,TYPE2,TYPE3(...)};
    de rajouter un membre sous la forme de
    qui prendrait comme valeur, fatalement, TYPE1,TYPE2 ou TYPE3 selon le type réel, et, dans ta méthode size(), utiliser un switch sur cette valeur sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    switch (LeTypeReel)
    {
        case TYPE1:
            return sizeof(Type1);
            break;
        case TYPE2:
            return sizeof(Type3);
            break;
    (...)
    }
    Evidemment, encore faut il que ce code s'adapte à ta situation propre...

    Une autre solution, qui ne passe pas par une énumération proprement dite, serait d'attaquer la recherche du contenu sous la forme de typeid et de son penchant type_info() (nécessite un #include<typeinfo>)

    Sauf erreur de ma part, meme dans une classe modèle, tu devrais etre en mesure de récupérer le type d'origine d'un objet quelconque...

    Tu pourrais donc envisager un code du genre de
    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
     
    const type_info &info=typeid(membre);
    //récupération du nom
    std::string nomtype.assing(info.what());
    //certains compilateur mettent des numéros avant les noms de types, 
    // supprimons les ;)
    nomtype=substr(nomtype.find_first_not_of("0123456789"),nomtype.size());
    // y a plus qua tester nomtype
     
    if(nomtype=="Type1")
    {
     
    }
    else if(nomtype=="Type2")
    {
     
    }
    (...)
    Penses à prendre "l'élément pointé par" quand tu utilises typeid() sur un pointeur

    NOTA: il y a peut etre des solutions plus jolies... à toi d'y regarder de plus près;-)
    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

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    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 296
    Par défaut
    Roulious a donné la solution la plus efficace => les typelists d'Andrei Alexandrescu (-> Modern C++ Design, Addisson-Wesley ; loki, sur sourceforge)
    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. Classe pour la création d'un graphe xy
    Par Bob dans le forum MFC
    Réponses: 24
    Dernier message: 03/12/2009, 17h20
  2. Enumération ou classe
    Par nathieb dans le forum Diagrammes de Classes
    Réponses: 6
    Dernier message: 25/10/2006, 19h26
  3. Réponses: 31
    Dernier message: 30/03/2006, 16h57
  4. [VB6]Enumérer les attributs et les méthodes d'une classe
    Par HPJ dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 04/05/2004, 18h34
  5. Sortir un typedef d'une classe
    Par Theophil dans le forum C++Builder
    Réponses: 13
    Dernier message: 03/07/2002, 17h21

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