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 :

comment gérer les énums dans un gros projet?


Sujet :

C++

  1. #1
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut comment gérer les énums dans un gros projet?
    Bonjour à tous,

    voilà, je travaille sur une application qui commence à prendre du poid, et je suis confronté au problème suivant:
    J'utilise tout un tas d'enum, car c'est extrêmement pratique pour la manipulation des données (pour les maps notamment). Mais j'aimerais avoir des enum dans lesquels je puisse déclarer les mêmes noms. Un exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    enum R_GroundType
    {
    	DEFAULT,
    	GRASS,
    	MUD,
    	WALL
    };
     
    enum R_UnitType
    {
    	DEFAULT, // interdit: redéfinition de DEFAULT
    	DEFAULT_ALIEN,
    	DEFAULT_ALIEN_SEL
    };
    J'aimerais trouver un moyen qui me permette de déclarer DEFAULT dans plusieurs enum différents.

    J'ai pensé à plusieurs solutions, et pour l'instant, je déclare mes enums dans des espace de nommage différents, mais cette solution est trés lourde et peu élégante.

    Avez-vous des idées concernant ce problème?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  2. #2
    Membre émérite
    Avatar de la drogue c'est mal
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    2 253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 2 253
    Points : 2 747
    Points
    2 747
    Par défaut
    ormis les namespace, pas trop
    il y a du linge sur la corde à linge

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Perso, je prefixe les valeurs des enum par leur type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    enum GroundType
    {
    	groundDefault,
    	groundGrass,
    	groundMud,
    	groundWall
    };
     
    enum UnitType
    {
    	unitDefault,
    	unitDefaultAlien,
    	unitDefaultAlienSel
    };
    (aussi, je reserve les identifiants tout en majuscules au préprocesseur).

  4. #4
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Points : 2 757
    Points
    2 757
    Par défaut
    Citation Envoyé par Sylvain Togni
    Perso, je prefixe les valeurs des enum par leur type
    (aussi, je reserve les identifiants tout en majuscules au préprocesseur).
    ~pareil

    e pour enum
    initiales du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    enum GroundType
    {
    	eGT_Default,
    	eGT_Grass,
    	eGT_Mud,
    	eGT_Wall
    };

  5. #5
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Points : 661
    Points
    661
    Par défaut
    j aime bien definir des types en plus de nommer mes enum un peu comme Sylvain Togni.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	typedef enum {	enPVIStateNoInit,
    			enPVIStateInit,
    			enPVIStateConnected,
    			enPVIStateDisconnected}
    enPVIState;
    Pour les details, cherche tout seul !

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je défini souvent des énums dans la classe qui en est le principal utilisateur, ce qui évite les conflits de nom. Je m'étais aussi amusé à définir chaque enum dans une classe faite pour l'occasion (qui faisait d'autres choses aussi, comme associer des chaines de caractère aux valeurs de l'enum), afin de forcer un préfixage de la valeur de l'énum par le nom de cette classe.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    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
    De plus en plus, je pars vers la seconde solution évoquée par Loïc.

    Aujourd'hui j'ai dû casser une application de la première utilisation car l'énuméré devait être utilisé dans la signature d'une tierce fonction, et que je ne voulais pas sacrifier la déclaration anticipé de la classe où était déclarée l'énum.

    En gros, je me retrouve avec ce genre de choses:
    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
    // TotoTitiFwd.h
    #ifndef TOTO_TITI_FWD_H_
    #define TOTO_TITI_FWD_H_
    namespace Toto {
        struct State {
            // si je me souviens bien, je crois que j'avais choisi une classe plutôt
            // qu'un espace de noms pour méta-programmer de temps à autres
            enum type { FIRST__=42, active=FIRST__, closed, END__ };
            // tous mes énumérés ont ce END__/LAST__/NBMAX__/...
        };
        std::string toString(State::type eState);
        State::type toEnum(std::string const& sState);
     
        class Titi; // la déclaration anticipée
    }
    #endif
    // endif TOTO_TITI_FWD_H_
     
     
    // TotoTiti.h
    #ifndef TOTO_TITI_H_
    #define TOTO_TITI_H_
    #include "TotoTitiFwd.h"
    namespace Toto {
        class Titi{ // la définition
            ...
            State::type getState() const;
            void setState(State::type eState);
        };
    }
    #endif
    // endif TOTO_TITI_H_
     
     
    // Tutu.h
    ....
    #include "TotoTitiFwd.h"
    // Ici, pas besoin de la définition de Toto::Titi, 
    // contrairement à la définition de l'enum
    void propagate(Toto::Titi & titi, Toto::State::type eState);
    ...
     
    // tata.cpp
    propagate(titi, Toto::State::active);
    Vous avez compris, je préfère préfixer par une portée (namespace + éventuellement classe) plutôt que par une série de caractères qui polluent, à mon goût, identifiants et types.


    Mais ...dernièrement, j'ai croisé un projet expérimental chez boost qui permettait de faire des choses super clean avec les enumérés. Je me demande si ce n'est pas loufoque qui en avait fait la pub ici.
    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...

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Ok. Merci pour votre participation. J'ai commencé à modifier mon code et à mettre le plus possible les enum dans les classes. En plus, c'est souvent logique de procéder ainsi.

    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  9. #9
    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
    Attention au détail des déclarations en avant.


    Et sinon, je suis tombé sur un article hier au sujet d'une évolution des énumérés pour le C++09.
    C'était très succinct, du coup je ne sais pas s'il y aura quoique ce soit pour itérer. De mémoire, cela ressemblait à ceci.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    enum class Type {
       val1, val2 
    };
     
    void f(Type);
     
    f(Type::val1);
    -> portée
    -> pas de convertion implicite vers int
    -> utilisation du mot clé "class" pour distinguer des "futurs anciens" énumérés
    -> je ne sais plus si il y aura des spéc précises au sujet de la taille
    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...

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    J'ai lu quelques papiers dans ce sens. Je n'ai pas eu l'impression qu'il y ait eu un consensus sur ce sujet, mais le document http://www.open-std.org/jtc1/sc22/wg...2006/n2122.htm semble indiquer le contraire.

    La proposition est très proche du C++/CLI, moins les fonctionnalités d'introspection, que je trouve pourtant très pratiques.

    Autrement, j'avais il y a quelque temps écrit du code pour avoir des enums typées fortement, et avec des possibilités d'itération et de conversion en chaînes. Je n'ai pas eu l'occasion de l'utiliser dans du vrai code, donc je ne sais pas à quel point ça tient la route, sachant que le but était aussi de m'amuser avec boost::preprocessor : RichEnum.h

    Ca s'utilisait comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DECLARE_RICH_ENUM(Range, (Self)(Touch)(Range10Feet)(Range50Feet)(Range100Feet));
    Range listAll = Range::begin();
    do
    {
        std::cout << listAll++ << std::endl;
    } while(listAll != Range::end());
    Et en test unitaire, j'avais :
    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
    Range r = Range::Touch;
    BOOST_CHECK_EQUAL(r, Range::Touch);
    r = Range::begin();
    BOOST_CHECK_EQUAL(r, Range::Self);
    BOOST_CHECK_EQUAL(++r, Range::Touch);
    BOOST_CHECK_EQUAL(r++, Range::Touch);
    BOOST_CHECK_EQUAL(++r, Range::Range50Feet);
    BOOST_CHECK_EQUAL(++r, Range::Range100Feet);
    BOOST_CHECK_EQUAL(++r, Range::end());
    BOOST_CHECK_EQUAL(++r, Range::end());
    BOOST_CHECK_EQUAL(--r, Range::Range100Feet);
    BOOST_CHECK_EQUAL(--r, Range::Range50Feet);
    BOOST_CHECK_EQUAL(--r, Range::Range10Feet);
    BOOST_CHECK_EQUAL(r--, Range::Range10Feet);
    BOOST_CHECK_EQUAL(--r, Range::Self);
    BOOST_CHECK_EQUAL(--r, Range::Self);
     
    r = Range::Touch;
    BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(r), "Touch");
    Ca résout les
    - problèmes de scope,
    - les problèmes d'introspection (itérer, convertir en chaîne compréhensible (mais pas la conversion dans l'autre sens, même si elle peut s'ajouter))
    - ceux de conversion implicite :pas de conversion vers int (je ne m'en sert jamais, donc même la conversion explicite me semblait de trop, on peut évidemment l'ajouter)

    Ca n'a même pas tenté de résoudre
    - les problèmes de taille, ce n'est pas ce qui m'intéressait, et je ne vois pas forcément comment le faire trivialement à partir de ce code.

    On ne sait jamais, si ça plaît à quelqu'un...
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

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

Discussions similaires

  1. Comment gérer les espaces dans un GridLayout
    Par Leniouns dans le forum SWT/JFace
    Réponses: 1
    Dernier message: 05/06/2013, 09h12
  2. [MySQL] Comment gérer les ' et " dans une table pour exporter en excel
    Par morgan47 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 30/11/2011, 19h42
  3. Comment gérer les apostrophes dans oracle
    Par jenyfer dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 07/11/2006, 14h23
  4. Réponses: 5
    Dernier message: 28/11/2005, 09h52
  5. Comment gérer les valeur Nulles dans une requête ?
    Par sondo dans le forum Bases de données
    Réponses: 3
    Dernier message: 16/03/2005, 11h02

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