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

Qt Discussion :

Petite question mécanique sur la suppression de QObject


Sujet :

Qt

  1. #1
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut Petite question mécanique sur la suppression de QObject
    Hello,

    J'ai pu lire ça dans la faq:
    http://qt.developpez.com/faq/?page=Q...qobject-membre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class monObj : QObject
    {
    QTimer m_timer;
    public :
        monObj ()
        {
            m_timer.setParent(this);
        }
    }
    "Il est très important que tous les QObject en membre d'une classe ait pour parent this."


    Ce qui me fait bizarre et que je ne comprends pas trop bien. Sauf erreur dans l'exemple ci dessus. L'ordre de destruction devrait être :

    1) destructeur de monObj
    2) destructeur de m_timer
    3) destructeur de QObject

    Si cela est bien correct, c'est le destructeur de QObject qui va détruire les enfants, donc entre autre m_timer mais ce dernier est déjà liquidé à ce moment-là.

    Selon mon interprétation de la doc, la destruction de m_timer a pour effet de le retirer de la liste des enfants de monObj, c'est pour cela en fait que je pense que ça ne fait pas d'erreur si m_timer n'existe plus au moment ou le destructeur de QObject fait le nettoyage.

    Ca me paraît confus, mais si mon analyse est correcte (ce qui reste à déterminer), on ne devrait pas appeler setParent(this) sur un QObject membre non pointeur.

    Vous pouvez m'aidez à comprendre?

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Points : 969
    Points
    969
    Par défaut
    Selon mon interprétation de la doc, la destruction de m_timer a pour effet de le retirer de la liste des enfants de monObj, c'est pour cela en fait que je pense que ça ne fait pas d'erreur si m_timer n'existe plus au moment ou le destructeur de QObject fait le nettoyage.

    Ca me paraît confus, mais si mon analyse est correcte (ce qui reste à déterminer), on ne devrait pas appeler setParent(this) sur un QObject membre non pointeur.

    Vous pouvez m'aidez à comprendre?
    Ton interprétation de la doc est la même que moi. Donc en effet, je ne pense pas qu'il soit nécessaire de faire un setParent pour une variable allouée "statiquement" (j'entends par là non pointeur). Après, je crois que pour les QWidgets, cela a une importance (notamment en ce qui concerne les layouts des fenêtres), et au pire il n'y a pas d'inconvénients à le faire.

    G.

  3. #3
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    En fait, dans les exemples de Qt il me semble qu'ils stockent toujours des pointeurs vers les QObject, et là effectivement ils donnent directement "this" au constructeur lorsque le membre est alloué.
    Comme ça le destructeur du parent liquide le QObject créé sans code additionnel dans la classe courante.

    En fait, il semble plutôt que tous les membres qui ne font pas du comptage de référence (donc hors QString, QList etc..) devraient être des pointeurs sauf cas particulier.

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Salut

    Citation Envoyé par _skip Voir le message
    1) destructeur de monObj
    2) destructeur de m_timer
    3) destructeur de QObject
    C'est du C++ donc les membres sont détruit avant
    1) destructeur de m_timer
    2) destructeur de monObj
    3) destructeur de QObject

    Après, je crois que pour les QWidgets, cela a une importance (notamment en ce qui concerne les layouts des fenêtres), et au pire il n'y a pas d'inconvénients à le faire.
    Pareil c'est une règle du C++ :
    les membres sont créés dans l'ordre de leurs déclaration et détruit dans l'ordre inverse.
    Donc avec la gestion de parent/enfant, il peut y avoir des problèmes. Utiliser un pointeur enlève ce problème.

    En fait, il semble plutôt que tous les membres qui ne font pas du comptage de référence (donc hors QString, QList etc..) devraient être des pointeurs sauf cas particulier.
    Surtout pas. Il n'y as pratiquement aucun intérêt à faire cela. A part ajouter de la complexité en devant gérer leur destruction. En plus ils utilisent le COW.

    Pourquoi faut il mettre un parent? Par ce que certain traitements qui s'applique sur un QObject va s'appliquer ou on besoin de ce lien parent/enfant sur ses QObject enfants :
    - moveToThread
    - les recherche de QObject enfants
    - ...

    Après, c'est recommandé. Pas obligatoire. Surtout dans un environnement multi-thread.
    [edit]
    Remarque, peut être qu'utiliser un pointeur est plus simple à comprendre.


    Peut être faut il clarifier la QR.

  5. #5
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Si ça t'embête pas qu'on discute de ça, c'est intéressant, tout cas pour moi.

    Citation Envoyé par yan Voir le message

    C'est du C++ donc les membres sont détruit avant
    1) destructeur de m_timer
    2) destructeur de monObj
    3) destructeur de QObject


    Pareil c'est une règle du C++ :
    les membres sont créés dans l'ordre de leurs déclaration et détruit dans l'ordre inverse.
    Alors t'es sûr de ça? Parce que selon mes connaissances (plus limitées que les tiennes sans doute je l'admet) c'est l'ordre inverse de complétion des constructeurs qui joue et non pas l'ordre d'invocation.

    D'ailleurs pour cause, dans le destructeur de monObj, tu es libre d'accéder aux propriétés des objets membres (ici m_timer), ce qui devrait signifier qu'il n'est pas liquidé.


    Surtout pas. Il n'y as pratiquement aucun intérêt à faire cela. A part ajouter de la complexité en devant gérer leur destruction. En plus ils utilisent le COW.
    Je me suis peut être mal exprimé mais j'étais en train de dire que les objets COW étaient bon candidats pour un stockage non-pointeur dans un classe.

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par _skip Voir le message
    Alors t'es sûr de ça? Parce que selon mes connaissances (plus limitées que les tiennes sans doute je l'admet) c'est l'ordre inverse de complétion des constructeurs qui joue et non pas l'ordre d'invocation.
    J'ai pas tous compris Je vais me faire un petit code. Mais je suis quasiment sure de moi. Ce qui est sure est que l'odre de destruction des membres est dans le sens inverse de l'ordre de construction.

    D'ailleurs pour cause, dans le destructeur de monObj, tu es libre d'accéder aux propriétés des objets membres (ici m_timer), ce qui devrait signifier qu'il n'est pas liquidé.
    la fonction que l'on appel destructeur est là pour permettre de faire des traitement sur l'instance avant la destruction mémoire. Donc oui tu y as accès. Mais une fois sorti de la fonction, la destruction mémoire commence.

  7. #7
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Citation Envoyé par yan Voir le message
    J'ai pas tous compris Je vais me faire un petit code. Mais je suis quasiment sure de moi. Ce qui est sure est que l'odre de destruction des membres est dans le sens inverse de l'ordre de construction.
    Mais tu parles d'ordre inverse d'invocation des constructeurs, or moi je veux dire par ordre inverse de complétion, (ordre de complétion = l'ordre dans lequel les constructeurs *retournent*).

    la fonction que l'on appel destructeur est là pour permettre de faire des traitement sur l'instance avant la destruction mémoire. Donc oui tu y as accès. Mais une fois sorti de la fonction, la destruction mémoire commence.
    Si l'objet membre a été liquidé, soit ça va planter, soit faire des trucs barges je dirai. Ca m'étonnerait vachement que ça marche *par bol* comme tu le dis.

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Voici un code. Ca sera peut être plus claire. J'ai l'impression que l'on dit la même chose.
    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
    #include <QtCore>
     
    struct A
    {
        A() {qDebug() <<"A"; }
        ~A() {qDebug() <<"-A"; }
    };
     
    struct B
    {
        B() {qDebug() <<"B"; }
        ~B() {qDebug() <<"-B"; }
    };
     
    struct C
    {
        A a;
        B b;
        C() {qDebug() <<"C";}
        ~C() {qDebug() <<"-C";}
    };
    struct D
    {
        B b;
        A a;
     
        D() {qDebug() <<"D";}
        ~D() {qDebug() <<"-D";}
    };
     
    struct E
    {
        B b;
        A a;
     
        E():a(),b() {qDebug() <<"E";}
        ~E() {qDebug() <<"-E";}
    };
    int main(int argc, char *argv[])
    {
     
        {
            qDebug()<<"const";
             C c;
            qDebug()<<"dest";
        }
        {
            qDebug()<<"const";
             D d;
            qDebug()<<"dest";
        }
        {
            qDebug()<<"const";
             E e;
            qDebug()<<"dest";
        }
       return 0;
    }


    Si l'objet membre a été liquidé, soit ça va planter, soit faire des trucs barges je dirai.
    si a cause du lien parent/enfant un membre (non pointeur) est détruit oui ca fait n'importe quoi. C'est pour cela que c'est très risqué avec les QWidget. Avec les autres, comme la destruction du this est faite après eux, y as pas de problème. Plus exactement, c'est le destructeur du QObject qui va détruire les QObject enfants. Mais comme les membres sont détruit avant cette appel, il n'y as pas de problème.

    Ca m'étonnerait vachement que ça marche *par bol* comme tu le dis.
    ? j'aimais dit cela

  9. #9
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Citation Envoyé par yan Voir le message
    Voici un code. Ca sera peut être plus claire. J'ai l'impression que l'on dit la même chose.
    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
    #include <QtCore>
     
    struct A
    {
        A() {qDebug() <<"A"; }
        ~A() {qDebug() <<"-A"; }
    };
     
    struct B
    {
        B() {qDebug() <<"B"; }
        ~B() {qDebug() <<"-B"; }
    };
     
    struct C
    {
        A a;
        B b;
        C() {qDebug() <<"C";}
        ~C() {qDebug() <<"-C";}
    };
    struct D
    {
        B b;
        A a;
     
        D() {qDebug() <<"D";}
        ~D() {qDebug() <<"-D";}
    };
     
    struct E
    {
        B b;
        A a;
     
        E():a(),b() {qDebug() <<"E";}
        ~E() {qDebug() <<"-E";}
    };
    int main(int argc, char *argv[])
    {
     
        {
            qDebug()<<"const";
             C c;
            qDebug()<<"dest";
        }
        {
            qDebug()<<"const";
             D d;
            qDebug()<<"dest";
        }
        {
            qDebug()<<"const";
             E e;
            qDebug()<<"dest";
        }
       return 0;
    }
    Ca confirme exactement ce que je dis, c'est l'ordre de complétion des constructeurs qui compte.

    Donc pour l'exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class monObj : QObject
    {
    QTimer m_timer;
    public :
        monObj ()
        {
            m_timer.setParent(this);
        }
    }
    L'ordre des destructeurs est :
    1) destructeur de monObj
    2) destructeur de m_timer
    3) destructeur de QObject

    Et m_timer est intacte lorsque tu le manipules dans le destructeur de monObj, ce n'est pas un résidus.

    Or toi tu as dit je cite :

    C'est du C++ donc les membres sont détruit avant
    1) destructeur de m_timer
    2) destructeur de monObj
    3) destructeur de QObject
    Ensuite :

    si a cause du lien parent/enfant un membre (non pointeur) est détruit oui ca fait n'importe quoi. C'est pour cela que c'est très risqué avec les QWidget. Avec les autres, comme la destruction du this est faite après eux, y as pas de problème.
    C'est pour cela que j'ai écrit que les QObject non pointeurs ne devraient pas à mon sens avoir de parent défini.

    Plus exactement, c'est le destructeur du QObject qui va détruire les QObject enfants. Mais comme les membres sont détruit avant cette appel, il n'y as pas de problème.
    Mais alors le lien de parenté est inutile dans pour la destruction, il rajoute juste des opérations pour se désenregistrer de son parent. Rompre un lien qui n'avait aucune raison d'être, Non?

    ? j'aimais dit cela
    Il me semble que tu disais que je pouvais accéder aux propriétés de m_timer dans le destructeur de monObj parce que la mémoire existait encore malgré que m_timer ait été liquidé. Sous-entendu que ça marchait mais que c'était pas juste, voilà pourquoi j'ai écrit "par bol"


    PS: J'espère que mes propos te semblent pas agressifs, c'est juste que c'est parfois subtiles ces trucs et je veux être sûr qu'on soit bien d'accord à la fin de ce topic.

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    On s'est mélangé les définitions.
    Dans mon explication je parlais de la destruction mémoire et non l'appel au destructeur.
    Donc on as tous les deux raisons
    Plus exactement comment ca se passe en gros
    CONSTRUCTEUR:
    1. Création de la mémoire
    2. Appel de la fonction init de la classe parent
    3. Appel des fonctions d'init de chaque membres (dans l'ordre de leur déclaration dans le .h)
    4. Appel de la fonction init de la classe


    DESTRUCTEUR:
    1. appel de la fonction de destruction de la classe
    2. appel des fonctions de destruction de chaque membre (dans l'ordre inverse de leur déclaration dans le .h)
    3. Appel de la fonction de destruction de la classe parent
    4. déallocation de la mémoire


    La phase de destruction est inversé à la phase de construction

    C'est pour cela que j'ai écrit que les QObject non pointeurs ne devraient pas à mon sens avoir de parent défini.

    Mais alors le lien de parenté est inutile dans pour la destruction, il rajoute juste des opérations pour se désenregistrer de son parent. Rompre un lien qui n'avait aucune raison d'être, Non?
    Le lien de parenté n'est pas pour la destruction. J'ai dit tous à l'heure :
    Citation Envoyé par yan
    Pourquoi faut il mettre un parent? Par ce que certain traitements qui s'applique sur un QObject va s'appliquer ou on besoin de ce lien parent/enfant sur ses QObject enfants :
    - moveToThread
    - les recherche de QObject enfants
    - ...

    Il me semble que tu disais que je pouvais accéder aux propriétés de m_timer dans le destructeur de monObj parce que la mémoire existait encore malgré que m_timer ait été liquidé. Sous-entendu que ça marchait mais que c'était pas juste
    On s'est pas compris effectivement


    PS: J'espère que mes propos te semblent pas agressifs, c'est juste que c'est parfois subtiles ces trucs et je veux être sûr qu'on soit bien d'accord à la fin de ce topic
    Pas de problème.

  11. #11
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Ok je pensais que c'était uniquement une histoire de destruction.

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Tu pense qu'il faut améliorer la QR?

  13. #13
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Peut être juste indiquer que la parenté n'est pas juste une histoire de deletion pour les membres non pointeurs. Ce que la doc officielle de Qt pourrait faire elle aussi remarque.
    Mais je sais pas, peut être que c'était évident pour tout le monde sauf moi.

  14. #14
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par _skip Voir le message
    Peut être juste indiquer que la parenté n'est pas juste une histoire de deletion pour les membres non pointeurs. Ce que la doc officielle de Qt pourrait faire elle aussi remarque.
    Mais je sais pas, peut être que c'était évident pour tout le monde sauf moi.
    Non, je ne pense pas que c'est évident. j'avais hésiter à entrer dans les détailles mais j'avais peur que cela la rende plus complexe.
    Pour utiliser un QObject sans pointeur, c'est pareil. Il faut savoir les limites.

    Peut être donner en règle plus simple :
    QObject = préférer pointeur + parent
    les autres = pointeur inutile

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

Discussions similaires

  1. petite question rapide sur boucle for
    Par KateA dans le forum C
    Réponses: 15
    Dernier message: 09/03/2010, 00h59
  2. Réponses: 15
    Dernier message: 04/08/2009, 00h08
  3. petite question générale sur index unique
    Par ctobini dans le forum Requêtes
    Réponses: 2
    Dernier message: 07/02/2008, 16h45
  4. Petite question générale sur Javascript
    Par skywaukers dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 02/11/2007, 18h49
  5. Petite question rapide sur allocation mémoire
    Par adn013 dans le forum Langage
    Réponses: 5
    Dernier message: 11/06/2007, 17h10

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