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++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 55
    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 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 036
    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 : 55
    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
    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 ?

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 55
    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".

  8. #8
    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)

  9. #9
    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.

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 57
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    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 ?
    Je ne redéfinis aucun comportement.

    Citation Envoyé par gbdivers Voir le message
    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)
    Effectivement si je n'ai pas de transition basée sur l'event il n'y aura pas de changement d'état. Un foreach pourrait être indiqué mais je ne souhaite pas boucler sur des machines à états qui n'ont pas l'event défini, histoire d'optimisation ; en effet je suis censé traiter un très très grand nombre d'évènement.

    Citation Envoyé par Emmanuel Deloget Voir le message
    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é.
    En fait je n'avais pas totalement réalisé que CBase<X> et CBase<Y> sont des types différents. C'est la première fois que j'utilise le CRTP

    Citation Envoyé par Emmanuel Deloget Voir le message
    Vu le système proposé, ça ressemble fort à un gros problème de conception.
    Le système a été réfléchi et c'est de façon volontaire que les méthodes virtuelles et les mécanismes "traditionnels" du polymorphisme n'ont pas été implémenté. C'est une recherche de performance, qui je crois, a amené les concepteurs de cette librairie vers ce type de programmation

    Une idée vient de me passer par la tête.

    Et si je définis une classe tout simple MBase
    Et que j'utilise l'héritage multiple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class CDerivedA : public CBase<CDerivedA> ,  MBase {
    }
    De cette façon je crée un conteneur avec MBase qui stocke bien mes objets CDerivedA, CDerivedB, ...
    Et à lorsque je récupère l'objet je peux appeler directement process_event

  11. #11
    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 Antonin08 Voir le message
    Je ne redéfinis aucun comportement.
    Donc tu n'as pas besoin de dériver la classe state_machine (et de créer plusieurs classes dérivées). Du coup, tu peux mettre toutes tes state_machine dans un même conteneur.

    Citation Envoyé par Antonin08 Voir le message
    Effectivement si je n'ai pas de transition basée sur l'event il n'y aura pas de changement d'état. Un foreach pourrait être indiqué mais je ne souhaite pas boucler sur des machines à états qui n'ont pas l'event défini, histoire d'optimisation ; en effet je suis censé traiter un très très grand nombre d'évènement.
    Soit ce sont des events "génériques" (c'est à dire non lié spécifiquement à une state_machine particulière) et dans ce cas, c'est le boulot de la state_machine de testé si l'event est pris en compte ou pas.
    Soit ce sont des events "spécifiques" (c'est à dire que tu as créé pour chaque state_machine une liste d'event) et dans ce cas, un simple mapping suffira pour récupérer la state_machine correspondante à un event.

    Mais l'argument des performances me semble limite :
    - le dispatching (retrouver la state_machine qui correspond à un event en particulier) sera probablement presque aussi coûteux que les tests (si tu utilises un vector<state_machine> et que l'event te retourne un index dans le vecteur)
    - la plupart de tes events ne déclencheront probablement pas de transition. Ce qui revient à dire que la plupart des events consomment du temps pour rien. Mais c'est le boulot de la machine à états d'être efficace dans le traitement des events. En voulant "pré-traiter" les events, tu piques un peu de la responsabilité de la machine à états.
    - jamais, jamais, jamais et jamais faire de l'optimsation sans avoir vérifier que c'est nécessaire ! Écris ton code de base en laissant les machines à états faire leurs boulots. Et si tu vois qu'il y a une perte de performance quelque part, tu améliores après (et comme tu as bien réfléchi à ta conception et que tu respectes les principes de la POO, l'évolution de ton code est très simple).

    Bref, fait un simple for_each sur chaque state_machine pour appeler process_event.

    Citation Envoyé par Antonin08 Voir le message
    En fait je n'avais pas totalement réalisé que CBase<X> et CBase<Y> sont des types différents. C'est la première fois que j'utilise le CRTP
    C'est pas un problème de compréhension du CRTP mais des templates : 2 instanciations différentes d'une même classe template avec de arguments différents sont bien 2 classes différentes.

    Citation Envoyé par Antonin08 Voir le message
    Le système a été réfléchi et c'est de façon volontaire que les méthodes virtuelles et les mécanismes "traditionnels" du polymorphisme n'ont pas été implémenté. C'est une recherche de performance, qui je crois, a amené les concepteurs de cette librairie vers ce type de programmation
    En fait, Emmanuel parlait de ta conception et pas celle de boost
    Boost est une bibliothèque suffisamment critique pour qu'elle soit validé en long, en large et en travers (et par des experts reconnus du C++) et qu'elle soit optimisé pour les performances (en autre). Mais la contrepartie est qu'elle est parfois difficile à utiliser pour les débutants (ou plutôt qu'elle est mal utilisée par les débutants).

    Citation Envoyé par Antonin08 Voir le message
    Une idée vient de me passer par la tête.
    Et si je définis une classe tout simple MBase
    Et que j'utilise l'héritage multiple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class CDerivedA : public CBase<CDerivedA> ,  MBase {
    }
    De cette façon je crée un conteneur avec MBase qui stocke bien mes objets CDerivedA, CDerivedB, ...
    Et à lorsque je récupère l'objet je peux appeler directement process_event
    Hum, c'est ce qui est proposé dans la documentation pour les events et les transitions... donc oui, c'est la méthode recommandée (mais en mettant en premier la classe parent puis la classe boost, je sais pas si ça change quelque chose ici).


    Donc pour résumé :
    - tu fais un vecteur/list de state_machine
    - tu créés tes transitions/états
    - pour chaque event, tu appelles process_event
    - tu vérifies les performances
    - tu optimises (ou pas)


    Question subsidiaire : pourquoi tu as plusieurs machines à états ? et combien en as tu ? comment gères tu la création de tes graphs d'états ?

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 57
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Donc tu n'as pas besoin de dériver la classe state_machine (et de créer plusieurs classes dérivées). Du coup, tu peux mettre toutes tes state_machine dans un même conteneur.
    Pas compris ?
    state_machine est une classe template je suis donc obligé de créer mes classes dérivées...

    Citation Envoyé par gbdivers Voir le message
    Soit ce sont des events "génériques" (c'est à dire non lié spécifiquement à une state_machine particulière) et dans ce cas, c'est le boulot de la state_machine de testé si l'event est pris en compte ou pas.
    Soit ce sont des events "spécifiques" (c'est à dire que tu as créé pour chaque state_machine une liste d'event) et dans ce cas, un simple mapping suffira pour récupérer la state_machine correspondante à un event.
    Ce sont des events "spécifiques", oui.
    Par mapping tu entends tester l'existence de l'event pour chaque state machine ?

    Citation Envoyé par gbdivers Voir le message
    Mais l'argument des performances me semble limite :
    - le dispatching (retrouver la state_machine qui correspond à un event en particulier) sera probablement presque aussi coûteux que les tests (si tu utilises un vector<state_machine> et que l'event te retourne un index dans le vecteur)
    - la plupart de tes events ne déclencheront probablement pas de transition. Ce qui revient à dire que la plupart des events consomment du temps pour rien. Mais c'est le boulot de la machine à états d'être efficace dans le traitement des events. En voulant "pré-traiter" les events, tu piques un peu de la responsabilité de la machine à états.
    - jamais, jamais, jamais et jamais faire de l'optimsation sans avoir vérifier que c'est nécessaire ! Écris ton code de base en laissant les machines à états faire leurs boulots. Et si tu vois qu'il y a une perte de performance quelque part, tu améliores après (et comme tu as bien réfléchi à ta conception et que tu respectes les principes de la POO, l'évolution de ton code est très simple).
    Je suis d'accord après quelques tests le traitement d'un évènement-transition n'est quasiment pas consommant (1million d'event -> 70ns) avec une machine à 4 états.

    Citation Envoyé par gbdivers Voir le message
    Bref, fait un simple for_each sur chaque state_machine pour appeler process_event.
    Oui si je n'avais pas plusieurs instances du même state_machine. Car dans ce cas là un event s'adresserait à toutes les instances d'un même state machine, ce qui n'est pas forcément voulu

    Citation Envoyé par gbdivers Voir le message
    C'est pas un problème de compréhension du CRTP mais des templates : 2 instanciations différentes d'une même classe template avec de arguments différents sont bien 2 classes différentes.
    Oui c'est très possible

    Citation Envoyé par gbdivers Voir le message
    Hum, c'est ce qui est proposé dans la documentation pour les events et les transitions... donc oui, c'est la méthode recommandée (mais en mettant en premier la classe parent puis la classe boost, je sais pas si ça change quelque chose ici).
    Je veux bien que tu me dises où tu as lu cette information dans la documentation. Je suis sûrement passé à coté

    Citation Envoyé par gbdivers Voir le message
    Question subsidiaire : pourquoi tu as plusieurs machines à états ? et combien en as tu ?
    Pourquoi je ne saurais vraiment le dire peut être pour simplifier l'écriture, gérer plusieurs points d'entrée, créer plusieurs instances, séparer les fonctionnalités...
    Il n'y a pas de limite mais disons entre 10 et 50 en moyenne.

    Citation Envoyé par gbdivers Voir le message
    comment gères tu la création de tes graphs d'états ?
    Kesako ?

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, 14h08
  2. Trouver le Type d'une classe template dynamiquement ?
    Par Serge Iovleff dans le forum Langage
    Réponses: 3
    Dernier message: 23/09/2005, 17h48
  3. [DLL/classe template] problème de link
    Par Bob.Killer dans le forum C++
    Réponses: 7
    Dernier message: 31/08/2005, 19h56
  4. Class template hérité
    Par Azharis dans le forum Langage
    Réponses: 4
    Dernier message: 24/06/2005, 23h03
  5. Réponses: 6
    Dernier message: 06/10/2004, 13h59

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