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 :

Un problème d'héritage


Sujet :

C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Terminal S
    Inscrit en
    Juin 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Terminal S

    Informations forums :
    Inscription : Juin 2013
    Messages : 30
    Points : 15
    Points
    15
    Par défaut Un problème d'héritage
    Bonjour, J'ai un petit problème, je présente mon cas:

    J'ai trois classes, une nommée MenuPrin, une autre nommée CurseEngine et une autre nommée MenuModule.
    Je me dis que CurseEngine va hérité de tous les modules, ici MenuModule. Je met toutes les fonctions de MenuModule en static pour un accès direct sans instancier la classe.

    Ensuit, c'est ici que ce pose mon problème, je veux créer une structure qui contient tout les informations du menu et les transmettre à MenuModule, mais je sais pas si il faut déclarer la structure dans les deux classes (MenuPrin et MenuModule).

    Schéma d’exécution :

    MenuPrin |-----(Demande un menu)-----> CurseEngine |--------(Utilise le module)----->MenuModule

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Citation Envoyé par Ninored Voir le message
    Je me dis que CurseEngine va hérité de tous les modules, ici MenuModule.
    Trèèès mauvaise idée ça.
    Tu va te retrouver avec des risques d'héritage en diamant, des risques de conflits avec les noms de méthodes, et j'en passe.

    Citation Envoyé par Ninored Voir le message
    Je met toutes les fonctions de MenuModule en static pour un accès direct sans instancier la classe.
    Erreur de conception.
    Si toute ta classe est utilisée via des méthodes statiques, c'est qu'il y a un problème.

    Déjà, est-ce que tu veux pouvoir ajouter/enlever dynamiquement un module pendant l'exécution de ton programme ?

    Là, comme ça je vois trois solutions :
    • utiliser un système de signaux/slots "à la Qt" ;
    • utiliser le design pattern singleton pour certains modules mais ce n'est pas une "bonne" solution sauf dans de très rares exceptions (module de logs) ;
    • une autre solution trop compliquée pour que j'en parle ici (si germinolegrand vois de quoi je parle ).


    Après c'est un problème qui est loin d'être évident, j'espère que Koala01 pourra t'apporter quelques éléments de réponses.

    Il faudrait que tu revoies ta conception.
    Est-ce que tu sais faire des diagrammes de classe UML ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Terminal S
    Inscrit en
    Juin 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Terminal S

    Informations forums :
    Inscription : Juin 2013
    Messages : 30
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par Neckara
    Déjà, est-ce que tu veux pouvoir ajouter/enlever dynamiquement un module pendant l'exécution de ton programme ?
    Non les modules ne seront pas ajouter/enlever dynamiquement.
    Je cherche en fait ici a pouvoir mettre plusieurs Moteurs graphiques, soi un moteur texte (libncurses ici nommé CurseEngine) et un moteur opengl, ou même directX si je fait un portage pour windows.
    Je pensais trouver plus simple de faire une sorte de boite qui va contenir toutes mes autres fonctions, pour bien les séparer. Après oui je voie que cela peut faire des problème pour l'héritage


    Citation Envoyé par Neckara
    Est-ce que tu sais faire des diagrammes de classe UML ?
    Je ne sais pas faire de vrai diagrammes UML, je fais simplement des boite représentent mes différentes classes au brouillon (sur un tableau) et j'établis des liens entre elles.


    J'aimerai que mon moteur texte puisse utiliser des threads et je me suis dit que CurseEngine va pouvoir, a ma demande, créer des threads pour faire les rendu et laisser la partie logique continuer. Mais je n'en suis pas encore à la ...

  4. #4
    Membre à l'essai
    Homme Profil pro
    Terminal S
    Inscrit en
    Juin 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Terminal S

    Informations forums :
    Inscription : Juin 2013
    Messages : 30
    Points : 15
    Points
    15
    Par défaut
    Je me trouve dans ce cas la:

    CurseEngine.hpp
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // il va inclure tout les modules. Je vais finalement pas créer une classe mais en faire plusieurs petite. 
    // (je me suis inspiré de la bibliothèque SFML), J'ai regardé l'un des header.
    #include "MenuModule.hpp"


    MenuModule.hpp
    Code cpp : 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
     
    #include <ncurses.h>
    class MenuModule
    {
     
        public:
            void menuMaker(infoMenu mInfoMenu); // Affiche le menu
     
        private:
    // structure posent problème
            struct infoMenu
            {
                int width;
                int height;
                int posX;
                int posY;
                // etc.
            } mInfoMenu;
    };


    MenuPrin.hpp
    Code c++ : 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
     
    #include "CurseEngine.hpp"
     
    class MenuPrin
    {
     
        public:
    // Fonctions constructeurs et d'autres
            void draw();
     
        private:
    // La même structure dans MenuModule.hpp
            struct infoMenu
            {
                int width;
                int height;
                int posX;
                int posY;
                // etc.
            } mInfoMenu;
    };
     
    void MenuPrin::draw()
    {
        menuMaker(mInfoMenu);
    }

    Le compilateur me revoie une erreur comme quoi mInfoMenu n'a pas été déclaré dans le MenuModule, je peux comprendre que le compilateur va différencier les deux structures mais dans ce cas comment faire ? Comment faire connaitre la structure des infos du menu au MenuModule.hpp ?
    Je ne voie pas comme faire connaitre cette structure a part la mettre en public dans la classe MenuModule et de faire hériter MenuPrin de celle-ci

  5. #5
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Erreur de conception.
    Si toute ta classe est utilisée via des méthodes statiques, c'est qu'il y a un problème.
    C'etait pour ce cas particulier ou de maniere generale ? Si c'est le deuxieme cas je ne suis pas de ton avis car il y a des fois ou ca offre un sacre confort.

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

    Informations professionnelles :
    Activité : aucun

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

    On m'a appelé, ben, me voilà... Excusez moi pour le délais de réponse, mais la semaine passée a été particulièrement chargé pour moi

    @Ninored Je crois sincèrement que tu pars dans une très mauvaise direction

    Si j'ai bien compris l'idée (dis moi si je me trompe), tu voudrais pouvoir créer un menu dont chaque élément ferait appel à un module particulier. Ai-je bon jusque là D'ici à ce que tu aies le temps de répondre à cette question, je vais faire "comme si" j'étais sur de ta réponse, et continuer mon raisonnement. Dans le pire des cas, les explications que je vais te fournir ici te seront sûrement utiles à un moment ou à un autre

    Si j'ai bien compris l'idée, ta classe MenuPrin n'est jamais qu'une classe qui présente un menu qui permettra à l'utilisateur de faire son choix. Cette classe peut, fatalement, contenir plusieurs éléments de menu. En gros, on peut s'attendre à ce qu'elle contienne un élément de menu par choix proposé à l'utilisateur. Cela nous mène tout naturellement à considérer la création d'une classe qui représente "n'importe quel élément du menu". Faisons simple et appelons cette classe MenuElement. Cette classe servirait de classe de base à tous les éléments du menu et pourrait exposer essentiellement deux fonctions dont le comportement devrait être adapté en fonction du type réel de l'élément de menu : print() pour pouvoir afficher le menu et execute() pour pouvoir exécuter la commande qui correspond à chaque élément de menu.

    Dans MenuPrin, tu pourrais donc te contenter de ne connaitre l'ensemble des éléments de menu que comme des (pointeurs sur des) objet de type MenuElement. De cette manière, tu pourais envisager d'avoir un code proche de (C++11 inside)
    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
    /* la classe de base commune à tous les éléments du menu
     * 
     * tu remarquera que les fonctions print et execute sont virtuelles pures, ce qui en fait un classe abstraite ;)
     */
    class MenuElement{
        public:
            virtual void print() const = 0;
            virtual void execute() const = 0;
            virtual ~MenuElement(){}
    };
    /* Ta classe menu en elle même */
    class MenuPrin{
        public:
            /* permet d'ajouter un nouvel élément de menu */
            void addNewElement(MenuElement * toadd){allMenuElements_.emplace_back(std::unique_ptr<MenuElement>(toadd));}
            void print() const{
                 for(auto const & it : allMenuElements_){
                     it.get()->print();
                 }
            }
            void execute(size_t toExecute) const{
                allMenuElements_[toExecute].get()->execute();
            }
        private:
        std::vector<std::unique_ptr<MenuElement>> allMenuElements_;
    };
    Ensuite, il y a le problème des modules qui seront appelés au travers des différents éléments de menu. Les modules ne sont pas des éléments de menu!!! Du simple aspect purement sémantique, cela n'a absolument pas de sens de dire qu'un module EST UN élément de menu. Tu ne peux donc pas envisager de faire hériter un module de MenuElement! Pire encore, chaque module devrait, a priori, être totalement indépendant du reste. Tu ne devrais donc pas avoir une classe ModuleBase, par exemple, qui servirait de classe de base à tes différents modules.

    Ainsi, si tu as N modules différents, hé bien, ce sont N classes différentes qui n'ont absolument aucun lien entre elles. Cela prendrait une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Module1{
        // tout ce qui est utile pour le premier module
    };
     
    Module2{
        // tout ce qui est utile pour le deuxième module
    };
    ...
    ModuleN{
        // tout ce qui est utile pour le Nième module
    };
    Par contre, je t'ai fait remarquer que MenuElement était une classe abstraite car les fonctions print et execute sont des fonctions virtuelle pures. Cela implique que tu devras, effectivement avoir des classes dérivées de MenuElement. Mais la différence par rapport à ce que tu envisages, c'est que ce ne sont pas des modules. Ce sont des éléments de menu qui utilisent chacun un module spécifique. Cela pourrait donc prendre la forme de
    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
    MenuForModule1 : public MenuElement{
        public:
            void print() const{
                // affichage spécifique pour le module1
            }
            void execute() const{
                // exécution spécifique pour le module1
            }
        private:
            Module1 module_;
    };
    MenuForModule2 : public MenuElement{
        public:
            void print() const{
                // affichage spécifique pour le module2
            }
            void execute() const{
                // exécution spécifique pour le module2
            }
        private:
            Module2 module_;
    };
    /* ...*/
     
    MenuForModuleN : public MenuElement{
        public:
            void print() const{
                // affichage spécifique pour le moduleN
            }
            void execute() const{
                // exécution spécifique pour le moduleN
            }
        private:
            ModuleN module_;
    };
    Et, à chaque fois que tu créeras un module complémentaire, tu créera une nouvelle classe dérivée de MenuElement qui l'utilisera "comme il doit être utilisé"

    De cette manière, tu pourras faire évoluer ton application strictement à ta guise, en évitant de te retrouver avec des hiérarchies de classes dans lesquelles certains héritages seraient aberrants
    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

  7. #7
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Ou la version sans héritage.
    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
    class MenuElement {
    public:
    	MenuElement(const std::string& name, std::function<void()> exec):
    		m_name(name), m_execute(std::move(exec))
    	{ }
    	void print() const { std::cout << m_name << std::endl; }
    	void execute() const { m_execute(); }
    private:
    	std::function<void()> m_execute;
    	const std::string m_name;
    };
     
    class MenuPrin{
    public:
    	void addNewElement(const std::string& name, std::function<void()> exec) {
    		m_allMenuElements.emplace_back(name, std::move(exec));
    	}
    	void print() const {
    		for(auto const & it : m_allMenuElements) {
    			it.print();
    		}
    	}
    	void execute(size_t toExecute) const {
    		m_allMenuElements[toExecute].execute();
    	}
    private:
    	std::vector<MenuElement> m_allMenuElements;
    };
    L'utilisation est identique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct Module1 { void run() { std::cout << "module1\n"; } };
    struct Module2 { void run() { std::cout << "module2\n"; } };
     
    MenuPrin menu;
    Module1 mod1;
    Module2 mod2;
    menu.addNewElement("module 1", [&mod1]() { mod1.run(); });
    menu.addNewElement("module 2", [&mod2]() { mod2.run(); });
     
    menu.print();
    menu.execute(0);
    menu.execute(1);

  8. #8
    Membre à l'essai
    Homme Profil pro
    Terminal S
    Inscrit en
    Juin 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Terminal S

    Informations forums :
    Inscription : Juin 2013
    Messages : 30
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par koala01
    Si j'ai bien compris l'idée (dis moi si je me trompe), tu voudrais pouvoir créer un menu dont chaque élément ferait appel à un module particulier. Ai-je bon jusque là
    Non ici le MenuModule va servir de module graphique pour la création de menu, on lui donnera seulement les info nécessaire a sa création ( ici mInfoMenu la fameuse structure). C'est la classe CurseEngine qui va gérer ces modules.
    Tout le projet ce trouve ici https://github.com/Ninored/TheCurses...e/CursesEngine

    je poste les fichiers importent:

    MenuPrin.hpp
    Code cpp : 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
    45
    46
    47
    48
    49
    50
    51
     
    #ifndef MENU_PRIN_HPP_
    #define MENU_PRIN_HPP_
     
    #include "GameState.hpp"
    #include "GameEngine.hpp"
    #include "CurseEngine.hpp"
    #include <ncurses.h>
     
    class MenuPrin: 
    	public GameState
    {
     
    public:
    	void Init();
    	void CleanUp();
     
    	void Pause();
    	void Resume();
     
    	void HandleEvent(GameEngine* game);
    	void Update(GameEngine* game);
    	void Draw(GameEngine* game);
     
    	static MenuPrin* Instance()
    	{
    			return &mMenuPrin;
    	}
     
    protected:
    	MenuPrin() { }
    	~MenuPrin() { }
     
    private:
    	static MenuPrin mMenuPrin;
    	const bool header[9][35] = {
               /* ... */
            };
     
    	int ch;
    	WINDOW* mWindow;
    	struct infoMenu
    	{
    		int height;
    		int width;
    		int posY;
    		int posX;
    	} mInfoMenu;
    };
     
    #endif // MENU_PRIN_HPP_


    CurseEngine.hpp
    Code cpp : 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
     
    #ifndef CURSE_ENGINE_HPP
    #define CURSE_ENGINE_HPP
     
    #include <vector>
    #include "MenuModule.hpp"
     
    class CurseEngine:
    	public MenuModule
    {
     
    public:
    	CurseEngine();
    	~CurseEngine();
     
    	static CurseEngine* Instance()
    	{
    		return &mCurseEngine;
    	}
     
    private:
    	static CurseEngine mCurseEngine;
    };
     
    #endif // CURSE_ENGINE_HPP

    MenuModule.hpp
    Code cpp : 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
     
    #ifndef MENU_MODULE_HPP
    #define MENU_MODULE_HPP
     
    class MenuModule
    {
    	public:
    		MenuModule();
    		~MenuModule();
    		void drawMenu(infoMenu *mInfoMenu);
    	private:
     
    	struct infoMenu
    	{
    		int height;
    		int width;
    		int posY;
    		int posX;
    	} mInfoMenu;
    };
     
    #endif // MENU_MODULE_HPP

    MenuPrin.cpp
    Code cpp : 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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    #include "GameState.hpp"
    #include "GameEngine.hpp"
    #include "MenuPrin.hpp"
    #include <iostream>
     
     
    MenuPrin MenuPrin::mMenuPrin;
     
     
    void MenuPrin::Init()
    {
    	mInfoMenu.cursorPos = 0;
    	mInfoMenu.posX = 0;
    	mInfoMenu.posY = 0;
     
    	getmaxyx(stdscr, mInfoMenu.height, mInfoMenu.width);
     
     
    	mWindow = newwin(mInfoMenu.height, mInfoMenu.width,
    					mInfoMenu.posY, mInfoMenu.posX);
    	nodelay(mWindow, TRUE);
     
     
    	/* Init Colors*/
    	start_color();
    	init_pair(1,COLOR_BLACK,COLOR_RED);
    	init_pair(2,COLOR_BLACK,COLOR_BLACK);
    	init_pair(3,COLOR_WHITE, COLOR_BLACK);
     
    	// TODO: Init vector data
    }
     
    void MenuPrin::CleanUp()
    {
    	delete mWindow;
    }
     
    void MenuPrin::Pause()
    {
    }
     
    void MenuPrin::Resume()
    {
    }
     
    void MenuPrin::HandleEvent(GameEngine* game)
    {
    	/* ... */
    }
     
    void MenuPrin::Update(GameEngine* game)
    {
    }
     
    void MenuPrin::Draw(GameEngine* game)
    {
    	//Print banner
    /* ... BANNER PRINT */
     
        CurseEngine::Instance()->drawMenu(&mInfoMenu);
     
        wrefresh(mWindow);
    	refresh();
    }

    Ici le compilateur renvoi :
    /TheCursesAdventure/src/MenuModule.hpp:9:17: error: ‘infoMenu’ has not been declared

  9. #9
    Membre à l'essai
    Homme Profil pro
    Terminal S
    Inscrit en
    Juin 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Terminal S

    Informations forums :
    Inscription : Juin 2013
    Messages : 30
    Points : 15
    Points
    15
    Par défaut
    Excusez moi, je n'ai pas eu le temps d'aller sur le forum a cause de la reprise des cours.

    Je fais un petit "up" car mon problème reste toujours le même.

Discussions similaires

  1. [C#] Problème d'héritage, aide svp :(
    Par choas dans le forum Windows Forms
    Réponses: 12
    Dernier message: 06/05/2006, 11h46
  2. problème constructeur + héritage
    Par BOLARD dans le forum C++
    Réponses: 10
    Dernier message: 13/04/2006, 08h11
  3. [AS2] Problème d'héritage
    Par wwave dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 27/01/2006, 09h26
  4. Problème d'héritage ?
    Par Romanops dans le forum WinDev
    Réponses: 2
    Dernier message: 16/11/2005, 17h18
  5. Problème d'héritage d'une méthode protégée
    Par shenron666 dans le forum C++
    Réponses: 9
    Dernier message: 28/04/2005, 23h17

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