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

Affichage des résultats du sondage: Quel est le meilleur emplacement pour ce typedef ?

Votants
7. Vous ne pouvez pas participer à ce sondage.
  • Dans la définition de la classe

    2 28,57%
  • Après la définition de la classe

    1 14,29%
  • Ça dépend…

    4 57,14%
  • Surtout pas dans le fichier d'en-tête !!!

    0 0%
  • C'est inutile, un typedef

    0 0%
C++ Discussion :

Position d'un typedef de conteneur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut Position d'un typedef de conteneur
    Bonjour,
    J'ai plus une question de « design » qu'un réel problème à vous soumettre.

    Le contexte est simple : une classe dont les instances sont stockées dans un (ou plusieurs) conteneur(s).
    Histoire de faciliter l'utilisation de ce conteneur, faire un « typedef » me paraît une bonne idée.

    Seulement, où est-il le plus judicieux de le placer ?
    Pour commencer, j'aurais tendance à penser que le fichier d'en-tête n'est pas un mauvais emplacement.
    Mais j'hésite entre le définir comme un type interne ou externe.
    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
    #include <vector>
     
    class UneClasse
    {
     
        public:
            // En type interne
            typedef std::vector<UneClasse> Vector;
     
        (...)
     
    }; // class UneClasse
     
     
    // En type externe
    typedef std::vector<UneClasse> UneClasseVector;
    Quitte à avoir les deux…
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <vector>
     
    class UneClasse
    {
     
        public:
            typedef std::vector<UneClasse> Vector;
     
        (...)
     
    }; // class UneClasse
     
    typedef UneClasse::Vector UneClasseVector;

    Ma première idée serait plutôt de faire un type interne…
    N'hésitez pas à laisser des avis commentés et autres remarques constructives !

    NB: Pour les plus rapides, un peu de patience…
    Des précisions arrivent.

  2. #2
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Bon, comme je le disais, voici quelques précisions concernant le projet qui m'amène cette question.

    Pour certaines classes, le conteneur est un attribut membre statique, dans lequel sont stockées toutes les instances.
    En passant, ces classes sont des usines/fabriques.
    Pour d'autres, c'est un attribut membre non statique d'une autre classe, dans lequel sont stockées uniquement les instances liées.

    Les classes manipulent parfois un de ces conteneurs (ou un sous-ensemble), parfois juste un élément.

    Et pour finir, polymorphisme oblige, ce sont plutôt des conteneurs de pointeurs que de conteneurs d'objets…
    Ça change quelque chose par rapport à ma question ?

    [edit]
    Les classes ont une sémantique d'entité.
    [/edit]

  3. #3
    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,

    A vrai dire, j'aurais tendance à déclarer le typedef dans... la classe qui devra contenir les instances de ma classe (c'est une solution que tu as oubliée dans le sondage) .

    J'en profiterai d'ailleurs sans doute pour ajouter un typedef sur les itérateurs utiles , mais je placerai le typedef sur le conteneur en accessibilité privée, alors que je placerai celui sur les itérateurs dans l'accessibilité qui s'y prête le mieux (sans doute publique pour les const_iterator, vraisemblablement privée pour les iterator)
    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
    class MaClasse
    {
        /* le contenu de MaClasse */
    };
    class MonConteneurDeClasse
    {
        typedef std::vector<MaClasse> vector; // pour la facilité uniquement, à
                                              // usage interne
        /* Peut être en accessibilité publique SSI il est opportun de permettre
         * la modification des instances
         * Sinon, il sera sans doute utile à usage interne ;)
         */
        typedef typename vector::iterator iterator; 
        public:
            /* pour autant que l'on veuille récupérer les instances en dehors
             * de MonConteneurDeClasse ;)
             */
            typedef typename vector::const_iterator const_iterator;
            /* par exemple : */
            const_iterator begin() const{return items.begin();}
            const_iterator end() const{return items.end();}
        private:
            vector items;
    }
    Pour justifier mon choix:

    1- Il se peut parfaitement que tu veuilles manipuler les différentes instances de ta classes sous la forme de collections différentes, en fonction des circonstances: un tableau dans une situation donnée, une map dans une autre situation, une liste dans une troisième, une pile, une file ou un set dans d'autres encore.

    La collection que tu choisira ne dépendra pas de la classe dont tu veux gérer les instances, mais bien de la classe qui a la responsabilité de les gérer

    Si tu donnes cette responsabilité à la classe elle-même, tu te trouvera dans une situation dans laquelle tu ne pourrais pas donner (en dehors de toute justification cohérente et tenant la route pour le faire) d'autre responsabilité à ta classe, en application du fameux principe de la responsabilité unique

    Le type de collection que tu utilisera est à considérer purement et simplement comme un détail d'implémentation de la classe qui a pour responsabilité de gérer les instances de ta classe: Afin de respecter Demeter (et toujours, en l'absence de justification cohérente pour ne pas le faire), tu ne devrais pas exposer ce détail d'implémentation en dehors de la classe .

    Il n'y a donc, a priori, aucune raison d'exposer le fait que le conteneur utilisé est de type std::machin_chose, que ce soit sous la forme d'un typedef ou non

    De plus, on ne peut absolument pas exclure le fait que tu décidera peut être, après moultes essais et benchmarks, de changer le type de collection utilisé

    Par contre, on peut envisager le fait que l'un des services que l'on attend de la classe dont la responsabilité est de gérer les instances de la classe soit, justement, de nous permettre d'accéder à ces instances, de préférence sous la forme d'instances constantes, mais, éventuellement aussi sous la forme d'instances modifiables (en fonction de la situation).

    Le fait d'exposer le typedef sur le const_iterator (voire, sur l' iterator) du conteneur, en plus des fonctions begin et end (au minimum) permettra à l'utilisateur d'accéder aux différentes instances contenues et te permettra d'envisager sereinement (sans crainte de casser le code auquel tu n'as pas accès) de changer le conteneur, du moins, dans la mesure où tu garde un conteneur compatible
    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

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Mal lu l'enoncé, mal répondu au sondage. Ma coulpe.

    On ne mets certainement pas le typedef dans la classe : ce n'est pas à la classe de choisir comment elle doit être utilisée. Et si l'utlisateur préfère une deque ? ou une list ? ou un array ? Tu va mettre tous les typedefs dans la classe ?

    La première bonne réponse, c'est que le typedef est à l'extérieur de la classe. Ou exactement, après ?

    Et bien, for logiquement, et comme le C++ nous l'apprends : là ou on en a besoin. Cf. koala01 pour une première réponse.

    Ensuite, on peut considérer le cas où la collection est utilisée de manière régulière un peu partout. Dans ce cas, on va mettre ce typedef dans l'espace de nom des utilisateurs : ainsi, les différents utilisateurs vont utiliser la même description, et non pas redéfinir leur type de collection en interne (ce qui pourrait provoquer des problèmes de comptabilités de types). A noter qu'on va faire aussi un typedef sur au moins iterator et const_iterator.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  5. #5
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Citation Envoyé par koala01 Voir le message
    A vrai dire, j'aurais tendance à déclarer le typedef dans... la classe qui devra contenir les instances de ma classe (c'est une solution que tu as oubliée dans le sondage) .
    Tu vas rire, mais c'est justement en me demandant où placer le typedef d'un conteneur utilisé (uniquement) dans une autre classe que je me suis décidé à créer ce topic…
    Pour le reste, tu m'as donné matière à réfléchir.

    Citation Envoyé par Emmanuel Deloget Voir le message
    Mal lu l'enoncé, mal répondu au sondage. Ma coulpe.
    Ah je vois, c'est toi qui a répondu « Dans la définition de la classe »…

    Citation Envoyé par Emmanuel Deloget Voir le message
    A noter qu'on va faire aussi un typedef sur au moins iterator et const_iterator.
    Pourquoi est-ce si important ?
    Qu'y a-t-il de mal à écrire : « MonConteneur::iterator » ?

  6. #6
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par défaut
    Qu'y a-t-il de mal à écrire : « MonConteneur::iterator » ?
    C'est long et moche . ceci couplé avec une fonction standard, ça deviens vite ugly à souhait!

  7. #7
    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
    Citation Envoyé par Steph_ng8 Voir le message
    Pourquoi est-ce si important ?
    Qu'y a-t-il de mal à écrire : « MonConteneur::iterator » ?
    outre la simplification du code, il faut comprendre que la collection est à classer dans la catégorie des "détails d'implémentation", alors que l'itérateur (certainement constant, potentiellement non constant) est souvent à classer dans ce que l'on est en droit d'espérer obtenir de la part de la classe qui gère la collection d'objets.

    Il y a, en effet, de grandes chances que l'on ait besoin des services offerts par des fonctions telles que begin et end (permettant d'itérer sur l'ensemble du contenu), find ou autres fonctions similaires, qui, classiquement, renverront un itérateur.

    C'est la raison pour laquelle je présente un code qui place le typedef sur le conteneur dans l'accessibilité privée (car il à usage interne uniquement), celui sur le const_iterator en accessibilité publique (car celui là a de grandes chances d'être utilisé) et que je ne me prononce pas sur la place du typedef sur l'iterateur (non constant), car sa position dépendra très certainement de son utilité (privé si à usage interne, publique si on souhaite pouvoir modifier l'objet itéré).
    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

Discussions similaires

  1. Position relative dans un conteneur en position relative
    Par artefact89 dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 24/11/2010, 17h16
  2. position d'un control sur un conteneur
    Par sefir dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 22/06/2007, 22h47
  3. CSS position relative / conteneur
    Par Invité dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 12/09/2006, 22h47
  4. position:relative augmente la taille du conteneur ?
    Par Lideln dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 14/08/2006, 14h03
  5. [Opera 7 & 8] Position absolue dans conteneur relatif
    Par Sub0 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 16
    Dernier message: 16/08/2005, 23h16

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