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 :

Doute pour faire un constructeur/constructeur de copie


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 69
    Par défaut Doute pour faire un constructeur/constructeur de copie
    Bonsoir,

    J'ai un doute sur mes constructeurs vu que j'ai des pointeurs comme données membres et que je suis pas très doué en pointeurs.
    Quelqu'un peut-il m'aider ?

    J'ai ça dans mon header :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MyClass
    {
    private:
      DWORD_PTR m_pToto;
     
    public:
      MyClass( );
      MyClass( const DWORD_PTR ptr );
      virtual ~MyClass( );
    };
    et j'ai ça comme constructeur et constructeur de copie dans le .cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    MyClass::MyClass( )
    {
      m_pToto = (DWORD_PTR) new CClassTruc();
      assert(m_pToto!= NULL);
    }
     
    MyClass::MyClass( const DWORD_PTR dwPtr )
    {
      m_pToto= (DWORD_PTR) new CClassTruc();
      m_pToto= dwPtr;
    }
    J'ai un gros doute sur mon constructeur de copie

    Merci.

    Bonne soirée.

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Déjà, MyClass( const DWORD_PTR ptr ); n'est pas la signature d'un constructeur par copie de MyClass. Une signature de construteur par copie pourrait être : MyClass( const MyClass &c );.

    Ensuite, la chose à faire dans ce constructeur dépend de la sémantique de ta classe. On ne peut pas deviner pour toi. Par contre, le code écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      m_pToto= (DWORD_PTR) new CClassTruc();
      m_pToto= dwPtr;
    va assigner une valeur à m_pToto, correspondant à de la mémoire juste allouée, puis l'écraser par une autre valeur juste après. Tu as donc du code inutile, et une fuite mémoire.

    Enfin, n'oublie pas dans les constructeurs d'utiliser de préférence les listes d'initialisation.

    Je te conseille de lire la section de la faq sur le sujet.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur .NET/C/C++
    Inscrit en
    Septembre 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET/C/C++
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2007
    Messages : 71
    Par défaut
    Petite question:
    Pourquoi utilises-tu des DWORD_PTR?
    Ne serai-t-il pas préférable de les remplacer par des CClassTruc* ?

    Sinon, je plusoie JolyLoic: tu alloue de la mémoire et écrase le pointeur juste après, tu as donc une fuite mémoire.
    Ensuite, ce que dois faire ton constructeur de copie va surtout dépendre de ce que tu veux :
    - Soit tes 2 objets utilisent 2 instances différentes de la classe CClassTruc
    - Soit elles se partagent la même instance.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 69
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Déjà, MyClass( const DWORD_PTR ptr ); n'est pas la signature d'un constructeur par copie de MyClass. Une signature de construteur par copie pourrait être : MyClass( const MyClass &c );.

    Ensuite, la chose à faire dans ce constructeur dépend de la sémantique de ta classe. On ne peut pas deviner pour toi. Par contre, le code écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      m_pToto= (DWORD_PTR) new CClassTruc();
      m_pToto= dwPtr;
    va assigner une valeur à m_pToto, correspondant à de la mémoire juste allouée, puis l'écraser par une autre valeur juste après. Tu as donc du code inutile, et une fuite mémoire.

    Enfin, n'oublie pas dans les constructeurs d'utiliser de préférence les listes d'initialisation.

    Je te conseille de lire la section de la faq sur le sujet.
    Ah oui bien sûr, je fais n'importe quoi.
    En fait mon problème est que je ne sais pas comment copier mon pointeur dans mon constructeur de copie.
    J'aurais bien envie de faire ça moi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    MyClass( const MyClass &c )
    {
      m_pToto = c.m_ptoto;
    }
    Mais je crois que ça ne va pas.
    Du coup je ferais bien ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    MyClass( const MyClass &c )
    {
      m_pToto= (DWORD_PTR) new CClassTruc();
      m_pToto = c.m_ptoto;
    }
    Mais là vous allez me dire que j'alloue de la mémoire et que je l'écrase aussitôt.
    Du coup je ne vois pas trop.

    Pourtant j'ai bien lu la faq ^^

    Citation Envoyé par bountykiler Voir le message
    Petite question:
    Pourquoi utilises-tu des DWORD_PTR?
    Ne serai-t-il pas préférable de les remplacer par des CClassTruc* ?

    Sinon, je plusoie JolyLoic: tu alloue de la mémoire et écrase le pointeur juste après, tu as donc une fuite mémoire.
    Ensuite, ce que dois faire ton constructeur de copie va surtout dépendre de ce que tu veux :
    - Soit tes 2 objets utilisent 2 instances différentes de la classe CClassTruc
    - Soit elles se partagent la même instance.
    Ah oui bien vu ^^
    En fait c'est parce que je suis en train de faire un wrapper et que ma ClassTruc ne doit pas être connue dans mon header
    parce que sinon mon programme qui contiendra un #include "MyClass" dépendra de MaClassTruc et il ne faut pas (dans mon cas).
    En fait MyClass encapsule la class ClassTruc et le seul moyen que j'ai trouvé c'est d'utiliser un DWORD_PTR pour manipuler MaClassTruc en 'anonyme'.

    Merci.

    Bonne journée.

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur .NET/C/C++
    Inscrit en
    Septembre 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET/C/C++
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2007
    Messages : 71
    Par défaut
    Citation Envoyé par ZeNoob Voir le message
    J'aurais bien envie de faire ça moi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    MyClass( const MyClass &c )
    {
      m_pToto = c.m_ptoto;
    }
    Mais je crois que ça ne va pas.
    En fait si, tu peux. Tes 2 objects vont alors contenir chacun un pointeur vers une même variable (de type CClassTruc). Cela n'est pas mauvais en soit, mais le problème est qu'alors au moment de détruire une object, tu ne saura pas si tu doit faire un delete ou pas sur ce pointeur (car tu ne sais pas si tu est le dernier objet à pointer dessus ou pas).
    Une solution alors est d'utiliser des shared_ptr.

    [QUOTE]
    Du coup je ferais bien ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    MyClass( const MyClass &c )
    {
      m_pToto= (DWORD_PTR) new CClassTruc();
      m_pToto = c.m_ptoto;
    }
    Dans ce cas tu a 2 objects ont chacun un pointeurs vers des objets CClassTruc distints. Pour y arriver, tu dois plutot faire quelque chose d u style:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    MyClass::MyClass(const MyClass &c )
    {
      if(c.m_ptoto)//Ce teste m'evite de dereferencer un pointeur null
          m_pToto = (DWORD_PTR) new CClassTruc((CClassTruc)(*c.m_ptoto));
      else
        m_pToto = NULL;
    }

  6. #6
    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,
    Citation Envoyé par ZeNoob Voir le message
    Ah oui bien vu ^^
    En fait c'est parce que je suis en train de faire un wrapper et que ma ClassTruc ne doit pas être connue dans mon header
    parce que sinon mon programme qui contiendra un #include "MyClass" dépendra de MaClassTruc et il ne faut pas (dans mon cas).
    En fait MyClass encapsule la class ClassTruc et le seul moyen que j'ai trouvé c'est d'utiliser un DWORD_PTR pour manipuler MaClassTruc en 'anonyme'.

    Merci.

    Bonne journée.
    Qu'est ce qui t'empêche d'utiliser la déclaration anticipée de la classe, et de travailler sur quelque chose comme
    MyClass.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MaClassTruc ; // déclaration anticipée de la classe (cf lien ci dessus)
    class MyClass
    {
        public:
            MyClass() ;
            MyClass(MyClass const & c);
            ~MyClass();
            void foo() /* const */;
        private:
            MaClassTruc * ptr+;
    }
    MyClass.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <MaClassTruc.h> //car, ici, il faut, de toutes manière connaitre MaClassTruc ;)
    #include <MyClass.h>
    // j'ai fais le choix de copier le contenu du pointeur, parce qu'il semble plus cohérent ;)
    MyClass::MyClass():ptr_(0){}
    MyClass::MyClass(MyClass const & c):
        ptr_(c.ptr_? new MaClassTruc(*(c.ptr) : 0){}
    MyClass::~MyClass()
    {
        delete ptr_;
    }
    void MyClass::foo() /* const */
    {
        ptr_->doSomething();
    }
    Ta classe MyClass aura, de toutes manières, une dépendance vis à vis de MaClasseTruc, "simplement" du fait qu'elle va utiliser cette dernière en interne...

    Mais, parce que tu as recours à la déclaration anticipée, tu permet à l'utilisateur de MyClass de ne rien connaitre de MaClassTruc pour manipuler MyClass: tant que tu n'essaye pas de rajouter, dans MyClass, une fonction qui utilise explicitement un objet de type MaClasseTruc, l'utilisateur n'aura strictement aucune raison de s'intéresser à cette classe (autre, bien sur, que l'envie de savoir ce qui se cache "derrière le voile" )

    Mais ce sera, quoi qu'il en soit, toujours mieux que d'en venir à travailler avec des types comme DWORD_PTR (qui n'existe que sous windows ) ou (est-ce pire ce n'est en tout cas pas mieux ) avec des void * et de commencer à les transtyper à chaque fois
    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
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 69
    Par défaut
    Salut et merci à vous,

    Déjà j'ai mis de côté l'idée d'utiliser un DWORD_PTR, je vais déjà essayer de le faire 'normalement', on verra plus tard pour mon problème ...
    Ensuite j'ai compris (je crois) comment initialiser un pointeur avec le constructeur d'une classe
    mais alors pour les classes ou objets comme char* je ne sais pas trop comment faire hormis une simple recopie de pointeurs.

    J'ai cherché des exemples, lu la FAQ et tout, rien trouvé, alors j'ai écrit une exemple moi-même, sûrement avec des erreurs ...
    alors je vous mets mon code avec mes recopies de pointeurs, si y'a des trucs qui cloches n'hésitez pas !

    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
    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    /**************** Fichier d'en-tête *****************/
     
    class CClassTest;
     
    class CMyCLass
    {
    protected:
    	char* 			m_pSzName;
    	CClassTest*		m_pTest;
     
    public:
    	CMyClass( );			// Constructeur par défaut.
    	virtual ~CMyClass( );		// Déstructeur.
     
    	CMyClass( const char* pSzName, const CClassTest* pTest );	// Constructeur.
    	CMyCLass( const CMyClass& myClass );						// Constructeur de recopie.
     
    	void		SetPtrName( char* pSzName );
    	void		SetPtrTest( CClassTest* pTest );
    	char*		GetPtrName( ) const { return m_pSzName; }
    	CClassTest* GetPtrTest( ) const { return m_pTest; }
    };
     
    /**************** Fichier cpp *****************/
     
    CMyClass::CMyClass( )
    {
    	m_pSzName	= NULL;
    	m_pTest		= NULL;
    }
     
    CMyClass::~CMyClass( )
    {
    	delete m_pSzName;
    	delete m_pTest;
    }
     
    CMyClass::CMyClass( const char* pSzName, const CClassTest* pTest )
    {
    	SetPtrName(pSzName);
    	SetPtrTest(pTest);
    }
     
    CMyClass::CMyCLass( const CMyClass& myClass )
    {
    	if ( myClass.m_pSzName == NULL )
    		m_pSzName = NULL
    	else
    		m_pSzName = myClass.m_pSzName;
     
    	if ( myClass.m_pTest == NULL )
    		m_pTest = NULL
    	else
    	{
    		delete m_pTest;
    		m_pTest = new CClassTest(*myClass.m_pTest);
    	}
    }
     
    void CMyClass::SetPtrName( char* pSzName )
    {
    	if ( pSzName == NULL )
    		m_pSzName = NULL;
    	else
    		m_pSzName = pSzName;
    }
     
    void CMyClass::SetPtrTest( CClassTest* pTest )
    {
    	if ( pTest == NULL )
    		m_pTest = NULL;
    	else
    	{
    		delete m_pTest;
    		m_pTest = new CClassTest(*pTest);
    	}
    }
    merci.

    Bonne journée.

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Bonjour,
    Déjà, ton compilo devrait péter sur la ligne 41.

    Ton problème, c'est qu'il te faut choisir, pour chaque pointeur membre, si ta classe est censée gérer sa durée de vie ou non.

    Ensuite, pour ton pointeur de CClassTest, savoir si la copie doit partager l'objet (envisager alors un comptage de références) ou le dupliquer...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 69
    Par défaut
    Bonsoir,

    Citation Envoyé par Médinoc Voir le message
    Bonjour,
    Déjà, ton compilo devrait péter sur la ligne 41.
    En fait j'ai écrit le code dans un éditeur de texte mais je ne l'ai pas compilé.
    Mais effectivement je ne peux sans doute pas appeler les fonction 'SetMachin' dans le constructeur.

    Bon mais mon problème c'est de savoir comment recopier un pointeur membre (dans un constructeur par recopie).

    Citation Envoyé par Médinoc Voir le message
    Ton problème, c'est qu'il te faut choisir, pour chaque pointeur membre, si ta classe est censée gérer sa durée de vie ou non.
    Bah je pensais qu'en faisant un delete dans le destructeur c'était géré.

    En fait je voyais les choses simplement :
    - Dans le constructeur je mets le pointeur à NULL.
    - Dans le destructeur je le détruis (delete).
    - et sinon bah c'est là que je ne sais pas trop ...

    dans mon code je vois un peu de tout :

    delete m_pTest
    m_pTest = new CClassTest(*myClass.m_pTest);
    ou bien
    m_pTest = new CClassTest(*myClass.m_pTest);
    ou bien
    m_pTest = pTest;

    Citation Envoyé par Médinoc Voir le message
    Ensuite, pour ton pointeur de CClassTest, savoir si la copie doit partager l'objet (envisager alors un comptage de références) ou le dupliquer...
    [/QUOTE]

    Houla, je ne te suis plus là.
    Tu veux dire que chaque pointeur devrait être accompagné d'un m_ptrCount qui compte tous les pointeurs qui pointent vers mon objet ?

    Enfin bref, je suis un peu paumé.

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Si chaque objet à toi doit posséder son propre CClassTest, alors le problème se règle vite: On recopie avec le constructeur de copie de CClassTest.
    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
    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
    class CClassTest;
     
    class CMyClass
    {
    protected:
    	CClassTest*		m_pTest;
     
    public:
    	CMyClass( );                            // Constructeur par défaut avec Création (par exemple)
    	explicit CMyClass( CClassTest* pTest ); // Constructeur avec Appropriation
    	CMyCLass( const CMyClass& myClass );    // Constructeur de recopie.
    	virtual ~CMyClass( );                   // Déstructeur.
    	CMyClass& operator=(CMyClass tmp);      // Opérateur d'affectation. 
    	                                        //Oui, on prend le param par valeur, pas par référence:
    	                                        //Dans certains cas ça évite une copie inutile
    	void Swap( CMyClass &other );
    };
     
    /**************** Fichier cpp *****************/
    #include "MyClass.h"
    #include "ClassTest.h"
     
    // Constructeur par défaut avec Création (par exemple)
    CMyClass::CMyClass( )
     : m_pTest(new CClassTest) //Création
    { }
     
    CMyClass::~CMyClass( )
    {
    	delete m_pTest;
    }
     
    // Constructeur avec Appropriation
    CMyClass::CMyClass( CClassTest* pTest ) //Il serait ss doute plus approprié de passer un std::unique_ptr<> pour montrer l'appropriation.
     : m_pTest(pTest) //Appropriation
    { }
     
    // Constructeur de recopie. 
    CMyClass::CMyCLass( const CMyClass& src )
     : m_pTest(src.m_pTest==NULL ? NULL : new CClassTest(*src.m_pTest)) //Recopie récursive
    { 
    }
     
    void CMyClass::Swap( CMyClass &other )
    {
    	CClassTest * pTest = other.m_pTest;
    	other.m_pTest = m_pTest;
    	m_pTest = pTest;
    }
     
    CMyClass& CMyClass::operator=(CMyClass tmp) //Copy
    {                                           //And
    	Swap(tmp);                          //Swap
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/08/2007, 14h09
  2. Problème pour faire une copie de fichier.
    Par damien99 dans le forum C++
    Réponses: 1
    Dernier message: 12/02/2006, 16h37
  3. probléme pour faire une copie de base de donnée
    Par nours33 dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 31/12/2005, 12h35
  4. [Conception][constructeur] pour faire un tableau
    Par vasilov dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 20/07/2005, 10h58
  5. [xsl] xsl juste pour faire copie d'un xml
    Par peppena dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 17/02/2004, 16h17

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