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 :

t-uple de taille variable


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut t-uple de taille variable
    Bonjour à tous, j'ai le problème suivant:
    J'ai un classe de Base dont dérivent 4 autres classes (A, B, C et D) et une classe M qui manipule ces 4 classes filles par le biais d'un vecteur de Base*.

    Mon problème est qu'à certains moments, j'ai besoin de connaitre le type des éléments du vecteur pour faire certaines opérations.

    Pour le moment, je m'en suis sorti en utilisant un visiteur mais ce qui m'ennuie c'est que mon vecteur à une structure particulière que je n'exploite pas; en effet un vecteur à la structure suivante : (ABC)^+D qui pourra peut être évoluer vers un (ABC)(BAB)^*D

    Je me demandais donc s'il existait une sorte de t-uple mais à taille variable (je peux avoir des mutations, par exemple, passer de ABCD à ABCABCD dans ma succession d'élément du vecteur) qui me permettrait de me passer du polymorphisme dynamique.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Points : 379
    Points
    379
    Par défaut
    Citation Envoyé par CedricMocquillon Voir le message
    Mon problème est qu'à certains moments, j'ai besoin de connaitre le type des éléments du vecteur pour faire certaines opérations.
    Si tel est le cas, alors le polymorphisme n'est pas adapté, et l'utilisation d'un vecteur de base* n'est peut-être pas une bonne idée, puisque l'intérêt du polymorphisme est justement de pouvoir utiliser ton vecteur de base* sans connaître leur type.

    Si tu dois vraiment connaître le type, tu pourrais rajouter un membre string "nom de la classe", mais ça fait un peu bricoleur du dimanche. Ou alors compléter tes classes pour pouvoir les utiliser sans connaître leur type en rajoutant des méthodes abstraites à ta classe base.

  3. #3
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    #include <typeinfo.h>
    typeid(T)

    Cela conviendrait-il ?

  4. #4
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Peut-être qu'un variant serait plus adapté ? Tu perds par contre l'interface commune, pas sûr que ça soit ce que tu veuilles...

  5. #5
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Tes classes A, B, C et D ont-elles un état ou seulement un comportement ?

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Au lieu d'avoir A, B, C, et D qui dérivent de Base, fais en sorte d'avoir ABC, BAB et D qui héritent de Base.
    Boost ftw

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    @Cheps En fait il y a une petite nuance:
    J'ai besoin d'utiliser le type réel de mes éléments dans ma classe M mais après il y a deux pistes:

    soit je ne connais pas le type de mes élément dans ma classe M et j'utilise le polymorphisme (directement dans la classe de base ou par le biais de visiteur) qui va se charger de le déterminer pour moi (c'est un peu le but du polymorphisme)

    soit j'ai un moyen de connaitre le type de mes éléments dans ma classe M et je me passerai bien d'un appel virtuel + le code qui va bien (soit "alourdir" mes classes avec une responsabilité de plus, soit me défausser sur un visiteur avec une multiplication de classes)


    Or il se trouve que j'ai un moyen de connaitre le type de mes éléments puisque mon vecteur respecte une structure particulière ((ABC)^+D). S'il n'y avait pas de répétition possible de ABC, j'utiliserai un t-uple (c'est pour ça que je parlais de t-uple de taille variable) c'est à ce niveau que j'ai besoin d'aide...

    @camboui: le typeid(T) revient peu ou prou à "rajouter un membre string "nom de la classe", je vais être obligé de faire un switch dessus non?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    @white_tentacle: j'ai encore jamais utilisé de variant mais ça à l'air de pouvoir convenir, je perdrai pas l'interface commune puisque dans tout les cas mes classes A, B, C, D hériteront toujours de Base

    @3DArchi: elles ont à la fois un état et des comportements

    @loufoque: j'ai du mal à voir où tu veux en venir et comment utiliser ta réponse

  9. #9
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par CedricMocquillon Voir le message
    (ABC)^+D
    ...
    (ABC)(BAB)^*D
    Je pense que j'ai rien compris.
    Que signifie ces écritures ?

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    C'est pour signifier qu'il y a répétition (+: une fois ou plus; *: 0 fois ou plus) donc par exemple pour (ABC)^+D ça veut dire que mon vecteur de B* est composé de la manière suivante:
    un élément de type A en position 0
    un élément de type B en position 1
    un élément de type C en position 2
    peut être un élément de type A en position 3
    peut être un élément de type B en position 4
    peut être un élément de type C en position 5
    ...
    peut être un élément de type A en position fin-3
    peut être un élément de type B en position fin-2
    peut être un élément de type C en position fin-1
    un élément de type D en position fin

    Je peux donc avoir des séquences de ce type:
    ABCD, ABCABCD, ABCDABCABCD, ...
    mais pas de ABCAD par exemple.
    Je sais pas si c'est plus clair maintenant?

  11. #11
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Oui, OK.
    Mais je ne vois en quoi le polymorphisme dynamique est gênant.
    Et je reviens sur typeid(): c'est prévu par le langage, pourquoi s'en priver si t'en a besoin ?

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    Si tout A doit etre suivi d'un B, que tout B doit etre suivi d'un C et que tout C doit être suivi d'un A ou d'un D, mais que tout D est, d'office "final", pourquoi ne pas rajouter une méthode "nextIsAllowed(Base* next) qui te donnerait la réponse sur base d'un dynamic_cast

    Cela te donnerait quelque chose proche de
    Base.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Base
    {
        public:
            virtual bool nextIsAllowed(Base* next) const = 0;
    };
    A.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class B;
    class A : public Base
    {
        public:
            virtual bool nextIsAllowed(Base * next) const
            {
                return (dynamic_cast<B*>(next)!=NULL);
            }
    };
    C.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class A;
    class D
    class C : public Base
    {
        public:
            virtual bool nextIsAllowed(Base * next) const
            {
                return (dynamic_cast<A*>(next)!=NULL||
                        dynamic_cast<D*>(next)!=NULL );
            }
    };
    D.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class D : public Base
    {
        public:
            virtual bool nextIsAllowed(Base *) const
            {
                return false;
            }
    };
    De cette manière, lorsque tu vérifie ton vecteur d'objet, tu peux très facilement vérifier si, oui ou non, les éléments sont dans le bon ordre
    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

  13. #13
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par CedricMocquillon Voir le message
    @loufoque: j'ai du mal à voir où tu veux en venir et comment utiliser ta réponse
    Je pense qu'il veut dire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class ABC : public base
    {
     A a;
    B b;
    C c;
    };
    class D : public base
    {};
    Et ensuite tu peux faire ton tuple<ABC,D> et ton vecteur dessus. Ou quelque chose de ce genre, j'imagine. En gros, A, B, et C individuellement ne te servent à rien autant te faire directement la classe du ou des motifs qui t'intéressent.

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    @camboui: j'ai rien contre le polymorphisme dynamique, mais comme je connais la structure (en terme de succession de types) de mon vecteur de Base*, je pensais pouvoir m'en servir (j'ai pris pour habitude de déterminer le maximum de choses possibles dès la compilation, ça peu détecter les problèmes à la compile plutôt qu'au runtime et on y gagne généralement en terme de temps d'exécution)

    @koala: effectivement, mais c'est toujours basé sur du polymorphisme dynamique.

    Je crois qu'en fin de compte, comme ma taille de vecteur peut varier "dynamiquement", je pense que je n'ai pas d'autre choix que d'utiliser d'une manière au d'une autre le polymorphisme dynamique ou d'utiliser un cast en fonction de la position de l'élément que j'utiliser (par exemple, si c'est le premier et que la taille du vecteur est > 1, je peux tranquillement le caster en A*, sinon je peux tranquillement le caster en D*). Je crois que même si ça peut paraitre un poil "crade", je vais utiliser cette dernière technique. En tout cas merci à tous pour votre participation

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Points : 379
    Points
    379
    Par défaut
    Je me répète, mais le but du polymorphisme c'est d'utiliser des objets sans connaître leur classe (si ce n'est la classe de base), donc ce n'est pas adapté si tu dois connaître la classe.

    Tu pourrais utiliser un liste chaînée mixte plutôt qu'un vecteur.

    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
     
    class A
    {
    B* next;
    }
     
    class B
    {
    C* next;
    }
     
    class C
    {
    A* next; //si null utiliser final 
    D* final; //si null utiliser next
    }

  16. #16
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    En fait, je ne vois pas très bien ce que tu peux reprocher au polymorphisme dynamique, car c'est bel et bien ce qu'il te faut dans le cas présent

    A l'extrême, tu te trouve face à un parser d'expression plus ou moins classique, à ceci près que les différents termes présentent tous des restrictions.

    Au final, si tu écartes la solution de loufoque (qui peut effectivement présenter un intérêt, mais je lui laisse le soin de défendre son idée ), soit, chaque classe dérivée devra avoir un minimum de connaissance de la classe qui peut suivre, soit tu dois travailler avec une classe "externe" à ta hiérarchie qui doit, elle, connaitre non seulement la classe de base, mais aussi l'ensemble des classes dérivées.

    Tu pourrais aussi envisager un pattern proche de la chaine de responsabilité ou du visiteur (chaque classe étant le visiteur de la classe qui peut suivre et le visité de la classe qui doit le précéder) voir une solultion exclusivement basée sur le RTTI (à coup de type_id), ou encore une solution basée sur les template et le "type erasure", il ne faut pas te faire d'illusions: cela aura un cout soit en terme de taille de l'exécutable, soit en terme de performances, si pas les deux...

    Et tu n'évitera pas, hormis si tu prend la peine de réfléchir à la solution proposée par loufoque, soit d'avoir une dépendance "circulaire" indirecte (A dépendant de B, B dépenant de C, C dépendant de A) soit une dépendance externe entre Base, A, B, C et D et une classe "vérificatrice".
    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

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/09/2006, 10h53
  2. [Beamer] Table des matières de taille variable
    Par jacklafrip dans le forum Beamer
    Réponses: 1
    Dernier message: 25/08/2006, 11h44
  3. objet de taille variable en attribut static
    Par BigNic dans le forum C++
    Réponses: 8
    Dernier message: 06/07/2006, 21h41
  4. [TP] Tableau de taille variable
    Par Ripley dans le forum Turbo Pascal
    Réponses: 4
    Dernier message: 30/01/2006, 15h36
  5. Comment obtenir un tableau à taille variable ?
    Par marsupilami34 dans le forum Langage
    Réponses: 6
    Dernier message: 27/06/2005, 15h03

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