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

Langage C++ Discussion :

Classe template et conteneur


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2008
    Messages : 57
    Par défaut Classe template et conteneur
    Bonjour,

    J'ai une classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    template<class Derived>
    CBase {
    };
    2 classes dérivées
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CDerivedA : public CBase <CDerivedA> {
    };
     
    CDerivedB : public CBase <CDerivedB> {
    };
    Est-ce qu'il es possible de créer un conteneur style map à partir de CBase pour y déposer CDerivedA et CDerivedB ??

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Oui, avec boost::variant ou boost::any

  3. #3
    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
    ... ou non, sans boost.variant (ou boost.any).

    CBase<X> est un type différente de CBase<Y>.
    [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.

  4. #4
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Je me disais aussi ... Tu peux effectivement faire dans CBase une std::map<MaClef, Derived>
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2008
    Messages : 57
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    ... ou non, sans boost.variant (ou boost.any).

    CBase<X> est un type différente de CBase<Y>.
    Ce qui veut dire que je ne peux pas considérer CBase comme classe de base ?

    Citation Envoyé par dragonjoker59 Voir le message
    Je me disais aussi ... Tu peux effectivement faire dans CBase une std::map<MaClef, Derived>
    Pour précision :
    J'utilise en ce moment Boost.Statechart. Et la classe de base est state_machine<MostDerived, InitialState>

    Ce qui veut dire je ne veux/peux pas modifier le code de CBase

    Mon intérêt ici est de pouvoir enregistrer dans un conteneur des objets de types différents. Mais je ne vois pas comment, aussi je cherche quelques pistes si vous avez des propositions...

    Citation Envoyé par gbdivers Voir le message
    Oui, avec boost::variant ou boost::any
    J'ai déjà regardé un peu Boost.variant mais pour récupérer mon objet il faut que je connaisse le type et bien sur je ne le connais pas à l'exécution

    Sans polymorphisme que devient-on ?

  6. #6
    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
    Citation Envoyé par Antonin08 Voir le message
    Ce qui veut dire que je ne peux pas considérer CBase comme classe de base ?
    CBase n'est PAS ta classe de base. CBase n'existe pas, seule CBase<T> existe. Et dans ton cas, c'est CBase<X>, ou CBase<Y> selon le type considéré.

    Citation Envoyé par Antonin08 Voir le message
    Sans polymorphisme que devient-on ?
    Tiens, on se met à parler philosophie maintenant ?

    Citation Envoyé par gbdivers Voir le message
    Pas compris. Tu déconseilles l'utilisation de boost variant/any ici ?
    Non, je disais juste que sans ça, ça ne pouvait pas marcher. Un pendant à ta réponse, en quelques sortes

    Ceci dit, si on veut parler design, alors là oui : partout ou un type variant est utilisé, un bébé lapin meurt. Il faut donc éviter au maximum de les utiliser

    Vu le système proposé, ça ressemble fort à un gros problème de conception.
    [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.

  7. #7
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    ... ou non, sans boost.variant (ou boost.any).
    Pas compris. Tu déconseilles l'utilisation de boost variant/any ici ?

    J'ai déjà regardé un peu Boost.variant mais pour récupérer mon objet il faut que je connaisse le type et bien sur je ne le connais pas à l'exécution
    Sans polymorphisme que devient-on ?
    Tu veux faire quoi de tes objets ? Si tu veux appeler une fonction spécifique de chaque classe, tu peux utiliser le pattern visitor. Tu peux aussi appeler une fonction de la base. Sinon, tu peux explicitement récupérer le type de CBase (mais cela est souvent du à un problème de conception).

    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
    template<class Derived>
    CBase {
       virtual void foo() const = 0;
    };
     
    CDerivedA : public CBase <CDerivedA> {
       virtual void foo() const { cout << "je suis A"; }
       void foo2() const { cout << "je suis encore A"; }
    };
     
    CDerivedB : public CBase <CDerivedB> {
       virtual void foo() const { cout << "je suis B"; }
       void foo2() const { cout << "je suis encore B"; }
    };
     
    struct output : public boost::static_visitor<> 
    { 
        void operator()(CBase <CDerivedA> const& d) const { d.foo2(); } 
        void operator()(CBase <CDerivedB> const& d) const { d.foo2(); } 
    }; 
     
    typedef boost::variant< CDerivedA, CDerivedB > cbase_t;
    map<int, cbase_t> une_map;
    une_map.insert(make_pair(0, CDerivedA()));
    une_map.insert(make_pair(1, CDerivedB()));
     
    // appelle de foo()
    BOOST_FOREACH(const map<int, cbase_t>::value_type& une_paire, une_map)
    {
       une_paire.second.foo();
    }
     
    // appelle de foo2()
    BOOST_FOREACH(const map<int, cbase_t>::value_type& une_paire, une_map)
    {
       boost::apply_visitor(output(), une_paire.second);
    }
     
    // Récupérer spécifiquement le type
    CDerivedA value = boost::get<CDerivedA>(une_map[0]);
    Le fait que les 2 classes dérivent de la même classe template de base (donc de 2 classes différentes après l'instanciation du template) n'a aucune utilité ici. Donc même pas besoin d'avoir des fonctions virtuelles.

    J'utilise en ce moment Boost.Statechart. Et la classe de base est state_machine<MostDerived, InitialState>
    Ce qui veut dire je ne veux/peux pas modifier le code de CBase
    Tu peux créer une classe CBase qui est lié à state_machine<MostDerived, InitialState> par composition. As tu réellement besoin de l'héritage et du CRTP ?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2008
    Messages : 57
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Tu veux faire quoi de tes objets ? Si tu veux appeler une fonction spécifique de chaque classe, tu peux utiliser le pattern visitor. Tu peux aussi appeler une fonction de la base. Sinon, tu peux explicitement récupérer le type de CBase (mais cela est souvent du à un problème de conception).
    Effectivement j'appelle la fonction process_event(const event_base & evt) qui aura pour effet de changer l'état de l'objet suivant l'évènement passé. C'est pour cela que je dois connaître le type de l'objet auquel je m'adresse. (clair !!! pas sur). Je ne peux adresser un évènement qui n'est pas reconnu par l'objet.

    Citation Envoyé par gbdivers Voir le message
    Tu peux créer une classe CBase qui est lié à state_machine<MostDerived, InitialState> par composition. As tu réellement besoin de l'héritage et du CRTP ?
    L'héritage oui pour avoir plusieurs objets distincts. Le CRTP est implémenté par la librairie. (pas le choix a priori)

    Par contre la composition peut être intéressante. Est-ce que tu pourrais développer un peu ta pensée ?

    Pour revenir à ton code, ce que je disais c'est que je ne connais pas à priori le type de l'objet qui je vais utiliser, je m'adresse à lui au travers d'un numéro (clé map par exempleà ou une chaîne de caractère "CDerivedX".

  9. #9
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    J'ai du mal à comprendre :
    - Tu as bien plusieurs machines à états, chacune de ces machines ayant sa propre liste d'états et de transitions ?
    - Tu as bien plusieurs types de machines à états, chacune de ces machines ayant un comportement spécifique ? Dans ce cas, quel comportement tu redéfinis ?

    De plus, les events ne sont pas spécifique d'une machine à états en particulier. Donc tu peux appeler process_event sur toutes tes machines à états, si tu ne définis pas une transition basée sur l'event, tu n'auras pas de changement d'états (ce qui revient à dire que tu veux faire sans problème un foreach)

Discussions similaires

  1. iterateur d'un conteneur template dans une classe template
    Par coyotte507 dans le forum Langage
    Réponses: 2
    Dernier message: 03/07/2009, 13h08
  2. Trouver le Type d'une classe template dynamiquement ?
    Par Serge Iovleff dans le forum Langage
    Réponses: 3
    Dernier message: 23/09/2005, 16h48
  3. [DLL/classe template] problème de link
    Par Bob.Killer dans le forum C++
    Réponses: 7
    Dernier message: 31/08/2005, 18h56
  4. Class template hérité
    Par Azharis dans le forum Langage
    Réponses: 4
    Dernier message: 24/06/2005, 22h03
  5. Réponses: 6
    Dernier message: 06/10/2004, 12h59

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