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 :

Quel est la difference?


Sujet :

C++

  1. #1
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut Quel est la difference?
    Bonjour,
    y as un truc que je ne pige pas trop. dans ce code
    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
    #include <iostream>
    #include <string>
    using namespace std;
    struct A
    {
        A(string & s):m_s(s){};
        string m_s;
    };
     
     
    int main()
    {
        A a("essai");
        cout << a.m_s << endl;
        return 0;
    }
    fait une erreur car "essai" n'est pas une string et ne peut donc être passé en référence. Ca ok.
    Par contre en ajoutant const dans le constructeur de A

    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
    #include <iostream>
    #include <string>
    using namespace std;
    struct A
    {
        A(string const & s):m_s(s){};
        string m_s;
    };
     
     
    int main()
    {
        A a("essai");
        cout << a.m_s << endl;
        return 0;
    }
    ce code compile et fonctionne!!!

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    La différence est que le deuxième peut servir d'opérateur de conversion implicite sous une forme qui serait proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void lafonction(const A& lavar)
    {
     
    }
    int main()
    {
        std::string ch="salut";
        lafonction(ch);
        /*...*/
        return 0;
    }
    Cela signifie que, si tu veux empêcher cette conversion automatique, tu devrais déclarer le constructeur sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    explicit A(const std::string&)
    Il me semble d'ailleurs que tu économisera une copie en passant le paramètre sous la forme de référence constante
    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

  3. #3
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Par défaut
    J'vais peut-etre dire des betises, mais il me semble que je sais pourquoi...

    Quand tu declare une chaine par "essai" au sein de ton code, le compilateur alloue un espace memoire pour cette chaine, y copie les caracteres e,s,s,a et i (peut-etre aussi un 0 terminal)

    Vu que tu as declaré cette chaine au sein de ton code, elle n'est pas allouée de façon dynamique, mais statique. Il ne faut donc pas laisser la possibilité au programmeur de modifier ce qu'il y a à ton adresse, car il risquerais d'ecraser d'autres constantes du programme (si tu y ecrit une chaine plus longue, par exemple)

    Donc, en specifiant const, ça marche, puisque "essai" est en fait un pointeur const vers une chaine.

    Et vu la signature de ta fonction, le compilateur a compris tout seul qu'il ne fallait pas créer une variable de type const char* en mémoire, mais une variable de type const string

    Ceci explique cela.

    A peu de choses près...

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    En fait, il faut bien comprendre que tu as un constructeur par copie pour la std::string qui est, comme tu t'en doutes, string(const std::string&)...

    D'un autre coté, tu as un constructeur de string qui correspond (grace au spécialisations, on est d'accord hein ) à string(const char*), mais qui est déclaré, sauf erreur, comme explicite (ne permet pas de créer la chaine sans spécifier qu'on veut le faire)...

    Dés lors, quand tu déclare ton constructeur sous la forme de
    il faut que tu fournisse une chaine existante, alors que, quand tu le déclare sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A(const std::string& ch)
    tu en arrive à:
    • créer une chaine temporaire avec le constructeur explicite qui
    • sera utilisé pour créer la chaine passée en argument grace au constructeur par copie et qui
    • servira pour le constructeur de A...

    Ce n'est surement pas tout à fait juste, mais l'idée générale est là
    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

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    A a("essai"); crée un temporaire non-nommé de type string pour le passer au constructeur de a.
    La norme refuse le passage par référence non-constante de temporaire non-nommé, mais je ne me souviens plus des raisons précises (entre autres, modifier un truc sur le point d'être détruit n'a pas vraiment de sens).
    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.

  6. #6
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Un troisième point de vue:

    En fait, le constructeur qui prend un unique objet par référence constante est appelé également opérateur de conversion.

    Par exemple:
    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
    struct Dum
    {
    	Dum(const int & num)
    	{
    		std::ostringstream oss;
    		oss << num;
    		m_str = oss.str();
    	}
    	std::string m_str;
    };
     
    int main()
    {
        Dum dum = 3; // convertion de int en Dum
    }
    C'est une autre façon de voir les choses, mais ça explique un peu aussi ce qu'il se passe.

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    A a("essai"); crée un temporaire non-nommé de type string pour le passer au constructeur de a.
    La norme refuse le passage par référence non-constante de temporaire non-nommé, mais je ne me souviens plus des raisons précises (entre autres, modifier un truc sur le point d'être détruit n'a pas vraiment de sens).
    C'est bien ce que je pensais.
    C'est super ça en faite.
    Mon problème n'était pas le constructeur mais le fait de pouvoir passer une chaîne de caractère de type C sur un "string const &".
    Je trouve cela trés puissant en faite.
    Ainsi pour une même fonction:
    1- le passage d'un string en paramètre d'entrée sera optimisé
    2- Mais on pourra y mettre autre chose. Du moment que l'on puisse le convertir en string

    Par rapport au thread de koala01 sur les références. Ca en montre un autre difference avec un pointeur, qui je trouve, n'est pas négligeable.

    Voici un autre code

    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 <iostream>
    #include <string>
    using namespace std;
     
    void test( string const & s)
    {
       cout << s << endl;
    }
    int main()
    {
        test("essai");
        return 0;
    }

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Attention au revers de la médaille, toutefois...
    http://blogs.msdn.com/oldnewthing/ar...24/605974.aspx
    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
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Attention au revers de la médaille, toutefois...
    http://blogs.msdn.com/oldnewthing/ar...24/605974.aspx
    C'est à dire?

  10. #10
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    C'est à dire que, justement, si tu déclares un argument comme référence constante, tu cours le risque de faire appel à un opérateur de conversion implicite...

    Pour une chaine de caractères, ce n'est pas *trop* grave, mais l'exemple présente un cas particulier qui peut, justement, provoquer des couacs majeurs
    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

  11. #11
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par koala01 Voir le message
    C'est à dire que, justement, si tu déclares un argument comme référence constante, tu cours le risque de faire appel à un opérateur de conversion implicite...

    Pour une chaine de caractères, ce n'est pas *trop* grave, mais l'exemple présente un cas particulier qui peut, justement, provoquer des couacs majeurs
    Ha ok. mais d'où l'utilisation de explicit
    lol, je croit que je viens de comprendre explicit

  12. #12
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    En fait, l'utilisation de explict sur le constructeur va obliger d'utiliser un objet existant lorsque l'on veut fournir un l'objet en parametre de fonction:
    Ainsi, la classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class LaClass
    {
       public:
            LaClass(int i);
    };
    permettrait d'appeler une fonction ayant le prototye de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void lafonct(const LaClass& );
    sous une forme proche de
    du fait que le constructeur prenant un seul argument sert d'opérateur de conversion...

    Par contre, si tu crée ta classe sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class LaClass
    {
        public:
            explicit LaClass(int i);
    };
    les seuls moyens pour pouvoir appeler la même fonction seront
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int i;
    lafonct(LaClass(i));
    /* OU */
    LaClass a(i);
    lafonct(a);
    et l'appel de
    provoquera une erreur de compilation...

    Voilà, tu sais maintenant tout
    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

  13. #13
    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
    Citation Envoyé par Médinoc Voir le message
    La norme refuse le passage par référence non-constante de temporaire non-nommé, mais je ne me souviens plus des raisons précises (entre autres, modifier un truc sur le point d'être détruit n'a pas vraiment de sens).
    C'est ça en gros. Sauf qu'en plus d'être sur le point d'être détruit, l'utilisateur n'y a même pas accès. L'exemple de base est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void incr(int &i) {++i;}
    int main()
    {
      double i = 0;
      incr(i);
    }
    S'il n'y avait pas cette règle, le code compilerait, mais ce serait probablement une erreur, la variable incrémentée étant le temporaire crée du manière invisible pour l'utilisateur.
    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.

  14. #14
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Le problème là n'est il pas plus un problème de conversion de int en double

    Je verrais personnellement bien pour reprendre ton exemple, et pour présenter le cas particulier un problème avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void incr(int &i) {++i;}
    int main()
    {
      incr(3);
    }
    qui provoque une erreur
    invalid initialization of non-const reference
    (meme si, de fait, on peut considérer que le code que tu présente fait appel à un opérateur de conversion implicite de double en int )
    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

  15. #15
    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
    Incrémenter 3 est demander d'incrémenter une constante, et non un temporaire. On n'est donc pas dans le cas de la règle en question.

    Incrémenter i peut sembler légitime à l'utilisateur, et compilerait et s'exécuterait sans cette règle, mais aurait un comportement surprenant (il le faisait dans les premières versions du C++). La conversion a créé un temporaire, et il est rare qu'on veuille le modifier.
    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.

  16. #16
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Incrémenter 3 est demander d'incrémenter une constante, et non un temporaire. On n'est donc pas dans le cas de la règle en question.

    Incrémenter i peut sembler légitime à l'utilisateur, et compilerait et s'exécuterait sans cette règle, mais aurait un comportement surprenant (il le faisait dans les premières versions du C++). La conversion a créé un temporaire, et il est rare qu'on veuille le modifier.
    OOOpppsss... de fait... j'étais un peu distrait sur ce coup...
    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

  17. #17
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    My 2 cents : moi je pense que ça avoir avec les lvalue vs. rvalue...

    Et ça me fait énormément penser à ce sujet : http://www.developpez.net/forums/sho...d.php?t=444881

    Mais je peux me tromper.

  18. #18
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    My 2 cents : moi je pense que ça avoir avec les lvalue vs. rvalue...

    Et ça me fait énormément penser à ce sujet : http://www.developpez.net/forums/sho...d.php?t=444881

    Mais je peux me tromper.
    Ouai c'est la même famille .
    C'est cool, ça complète la réponse, je trouve.

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

Discussions similaires

  1. quel est la difference entre merise et uml
    Par mghari11 dans le forum Modélisation
    Réponses: 1
    Dernier message: 07/05/2011, 19h41
  2. Quel est La difference Entre Module Standard Et Module Classe
    Par r.mehdi dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 04/06/2008, 12h39
  3. Jboss et Jboss Seam quel est la difference ?
    Par ambhcie dans le forum Seam
    Réponses: 6
    Dernier message: 02/08/2007, 12h36
  4. quel est la difference ?
    Par yan dans le forum C++
    Réponses: 10
    Dernier message: 22/06/2007, 17h02
  5. Quel est la différence entre SUSE et mandrake
    Par pierrot10 dans le forum Distributions
    Réponses: 9
    Dernier message: 04/06/2006, 19h01

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