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 :

Erreur "must be a nonstatic member function" qui persiste inlassablement !


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut Erreur "must be a nonstatic member function" qui persiste inlassablement !
    Bonjour a tous,
    Voici mon probleme:

    Polynome.cxx
    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
    #include "RacineFonctions.hxx"
    
    #ifndef POLYNOME
    #define POLYNOME
    
    class Polynome : public RacineFonctions
    {
    	private:
    	int Degre;
    	double* Coefficients;
    
    	public:
    	Polynome(void);
    	Polynome(const Polynome&);
    	Polynome(int=0, double* = NULL);
    	~Polynome(void);
    	double Evalue(int, double) ;
    	Intervalle Evalue(int, const Intervalle&) ;
    
    	Polynome operator = (const Polynome&);
    };
    #endif
    Polynome.hxx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Polynome operator = (const Polynome &Q)
    {
    	double C[Q.Degre];
    	for (int i=0; i<Q.Degre; i++)
    	{
    		C[i]=Q.Coefficients[i];
    	}
    	Polynome R(Q.Degre, C);
    	return R;
    }
    Compilateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Polynome.cxx:40: error: ‘Polynome operator=(const Polynome&)’ must be a nonstatic member function
    Et cette erreur persiste meme si je remplace la variable de sortie par Polynome&, le parametre par Polynome& ou par Polynome, que j'ajoute const a la fin du prototype et que je modifie le code de la fonction.

    Je precise que Polynome herite d'une classe abstraite RacineFonctions, qui contient deux fonctions virtuelles, inutilisee pour l'instant.

    Ces deux derniers paragraphes resument tout ce que j'ai pu trouver comme potentielles solutions sur Google, mais je n'ai nulle part trouve une explication pertinente de ce que signifie cette erreur.

    Merci d'avance.

  2. #2
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Peut être avec ce code là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Polynome Polynome::operator = (const Polynome &Q)
    {
        ...
    }

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

    Informations professionnelles :
    Activité : aucun

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

    Heu, d'abord et avant tout, j'ai l'impression que tu as fait une fameuse soupe entre ton fichier d'en-tête et ton fichier d'implémentation...:

    Exception faite de la directive #include "RacineFonctions.hxx", le contenu de Polynome.cxx ressemble à s'y méprendre avec ce qui devrait se trouver dans... Polynome.hxx, alors que ce que l'on trouve dans Polynome.hxx devrait, en réalité, se trouver (avec d'autres choses) dans... Polynome.cxx.

    Ceci étant dit.

    L'opérateur d'affectation (operator = ) fait partie de ce que l' on appelle classiquement "le big four", et qui représente les quatre fonctions indispensables pour respecter la "forme canonique de coplien".

    Il doit donc impérativement être, ainsi que ton compilateur te le fait savoir, une fonction membre non statique de ton objet.

    Tu le déclares effectivement comme tel dans la classe (même si tu le fais dans le cxx ), mais, par contre, son implémentation (qui elle se trouve dans le hxx !!) ne permet pas au compilateur de se rendre compte que l'opérateur est, bel et bien, l'opérateur d'affectation de ta classe polynome :

    En effet, si tu peux définir les fonctions directement dans la déclaration d'une classe sans préciser la portée, il faut impérativement, si l'implémentation d'une fonction membre de classe est "déportée" (comprend: effectuée en dehors de la classe elle-même, comme, par exemple, dans un fichier *.cpp), que l'implémentation soit "pleinement qualifiée", et donc que la portée de la classe soit explicitement indiquée.

    Au final, tu pourrait avoir soit l'ensemble des définition des fonctions membres dans le fichier .hxx (pour les fonctions courtes, cela reste envisageable, bien que peu recommandable) sous 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
    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
    #ifndef POLYNOME
    #define POLYNOME
     
    class Polynome : public RacineFonctions
    {
        private:
            int Degre;
            double* Coefficients;
     
        public:
            Polynome(): /* liste d'initialisation */ //void n'est pas nécessaire dans le cas présent
            {
                 /*...*/
            }
            Polynome(const Polynome& poly) : /* liste d'initialisation */
            {
                 /*...*/
            }
            /* !!! DANGER : le fait que tous les paramètres aient une valeur par
             * défaut fait que ce constructeur entrera en conflit avec le
             * constructeur par défaut (ne prenant pas d'argument) !!!
             */
            Polynome(int i =0, double* ptrd = NULL) : /* liste d'initialisation */
            {
                 /*...*/
            }
            ~Polynome() //void n'est pas nécessaire dans le cas présent
            {
                 /*...*/
            }
     
            /* !!! DANGER : en imaginant que double et intervale soient, 
             * effectivement deux type différent, il est particulièrement
             * dangeureux d'avoir une fonction susceptible de renvoyer deux
             * types différents, en fonction des arguments qui sont passés
             *
             * Ce n'est pas interdit (parce que, par chance, le type des
             * arguments est différent ) mais il faut savoir que le type de retour
             * n'est pas pris en compte dans la signature des fonction, et tu
             * as donc un risque important de conflit entre les deux fonctions
             * ci-dessous
             */
            double Evalue(int i , double d) ; // celle ci sera surement mieux dans le *.cpp
            Intervalle Evalue(int i, const Intervalle& ival) ;// celle ci sera surement mieux dans le *.cpp
     
    	Polynome operator = (const Polynome& p)
            {
                 /*...*/
            }
     
    };
    #endif
    soit de "déporter" correctement l'ensemble des fonctions, ce qui donnerait alors quelque chose proche de
    Polynome.hpp
    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
    #ifndef POLYNOME_HPP
    #define POLYNOME_HPP
     
    class Polynome : public RacineFonctions
    {
        private:
            int Degre;
            double* Coefficients;
        public:
            Polynome() ;
            Polynome(const Polynome&);
            Polynome(int, double* = NULL);
            ~Polynome();
            double EvalueDouble(int, double) ; 
            Intervalle EvalueIntervale(int, const Intervalle&) ;
            Polynome operator = (const Polynome&);
     
    };
    #endif
    Polynome.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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include "Polynome.hpp"
    /* définition des constructeur */
    Polynome::Polynome() : /* liste d'initialisation */
    {
        /* ... */
    }
    Polynome::Polynome(const Polynome& p) : /* liste d'initialisation */
    {
        /* ... */
    }
    Polynome::Polynome(int i, double* ptrd) : /* liste d'initialisation */
    {
        /* ... */
    }
    Polynome::~Polynome() 
    {
        /* ... */
    }
    Polynome Polynome::operator = (const Polynome& poly)
    {
        /*...*/
    }
    double Polynome::EvalueDouble(int i, double d)
    {
    }
    Intervalle Polynome::EvalueIntervale(int i, const Intervalle& ival)
    {
        /* ...*/
    }
    Enfin, je n'aurais pas l'impression d'être complet si je ne mettais pas en évidence le fait que, selon moi, Polynome ne devrait pas hériter de RacineFonctions...

    Il n'est pas exclu (il est même plus que vraisemblable d'ailleurs) que Polynome utilise une RacineFonction en interne, on peut imaginer qu'un polynome puisse partager une partie de son interface publique avec RacineFonction (et encore !!!), mais, de là à dire qu'un Polynome EST un RacineFonctions, il y a de la marge et cela me semble particulièrement incorrect, sémantiquement parlant
    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

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Kalith Voir le message
    Peut être avec ce code là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Polynome Polynome::operator = (const Polynome &Q)
    {
        ...
    }
    WHOA !!! CA MARCHE DU PREMIER COUP !!!
    Alors qu'hier j'ai essaye de resoudre l'erreur pendant plusieurs heures. Je suis sur d'avoir deja essaye cette solution, mais il devait me manquer quelque chose ailleurs... merci !

    Citation Envoyé par koala01
    soit de "déporter" correctement l'ensemble des fonctions, ce qui donnerait alors quelque chose proche de
    Polynome.hpp
    C'est exactement ce que j'ai fait. Tu ne l'as peut-etre pas bien vu parce que je n'ai pas mis tout mon code en ligne.

    Citation Envoyé par koala01
    /* !!! DANGER : le fait que tous les paramètres aient une valeur par
    * défaut fait que ce constructeur entrera en conflit avec le
    * constructeur par défaut (ne prenant pas d'argument) !!!
    */
    Ca fait partie des exigences du prof (c'est lui qui a mis les parametres par defaut). En fait, je croyais que la "base canonique" imposait de faire un constructeur vide, ce qui n'est apparemment pas le cas, d'apres un camarade de classe. Donc, fixed !

    Citation Envoyé par koala01
    /* !!! DANGER : en imaginant que double et intervale soient,
    * effectivement deux type différent, il est particulièrement
    * dangeureux d'avoir une fonction susceptible de renvoyer deux
    * types différents, en fonction des arguments qui sont passés
    *
    * Ce n'est pas interdit (parce que, par chance, le type des
    * arguments est différent ) mais il faut savoir que le type de retour
    * n'est pas pris en compte dans la signature des fonction, et tu
    * as donc un risque important de conflit entre les deux fonctions
    * ci-dessous
    */
    Va falloir que je transmette ca au prof parce que c'est son code a lui...

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Citation Envoyé par User Name Voir le message
    C'est exactement ce que j'ai fait. Tu ne l'as peut-etre pas bien vu parce que je n'ai pas mis tout mon code en ligne.
    Si ce n'est que tu avais mis l'implémentation dans le fichier d'en-tête et le contenu du fichier d'en-tete dans le fichier d'implémentation, ce qui est assez mal vu
    Ca fait partie des exigences du prof (c'est lui qui a mis les parametres par defaut). En fait, je croyais que la "base canonique" imposait de faire un constructeur vide, ce qui n'est apparemment pas le cas, d'apres un camarade de classe. Donc, fixed !
    Alors:

    Primo, la forme canonique de coplien est créée de manière automatique par le compilateur: Si l'une des fonctions qui interviennent dans cette forme n'est pas fournie par toi, le compilateur fournira une version qui, pour autant que tu n'utilise pas de pointeur en interne, sera souvent "largement suffisante".

    Secundo : Tout argument ayant une valeur par défaut peut purement et simplement être omis lors de l'appel, pour autant qu'il ne s'agisse pas de fournir un argument juste après celui que l'on ommet (interdiction, par exemple, de passer un pointeur sur double au constructeur si on a ommis de passer l'entier ). Cela implique que, comme il est possible d'ommettre le premier paramètre (pour autant que l'on ommette également le second ), le constructeur prenant normalement deux arguments ayant chacun une valeur par défaut peut parfaitement servir de constructeur "vide"
    Va falloir que je transmette ca au prof parce que c'est son code a lui...
    Oh que oui...
    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

  6. #6
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 262
    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 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Tu peux lui dire aussi que son opérateur d'affectation n'est pas bon non plus

    ...
    c'est pas gagné
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut
    L'operateur d'affectation c'est moi qui l'ai fait : le prof nous demande seulement de le faire, mais n'indique rien dessus. Neanmoins, j'aimerais comprendre pourquoi il ne marche pas.

    Si je fais:
    Prototype dans Polynome.hxx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    friend Polynome operator = (const Polynome&);
    Fonction dans Polynome.cxx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Polynome Polynome::operator = (const Polynome &Q) //A refaire
    {
    	double C[Q.Degre];
    	for (int i=0; i<Q.Degre; i++)
    	{
    		C[i]=Q.Coefficients[i];
    	}
    	Polynome R(Q.Degre, C);
    	return R;
    }
    J'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Polynome.hxx:23: error: ‘Polynome operator=(const Polynome&)’ must be a nonstatic member function
    Polynome.cxx:67: error: prototype for ‘Polynome Polynome::operator=(const Polynome&)’ does not match any in class ‘Polynome’
    Polynome.hxx:10: error: candidate is: Polynome& Polynome::operator=(const Polynome&)
    Polynome.hxx:23: error: ‘Polynome operator=(const Polynome&)’ must be a nonstatic member function
    C'est notamment l'erreur en gras qui me casse les c++, pour rester poli !

    Si je fais la meme chose sans le friend dans le prototype, le programme compile, mais l'operateur ne marche pas (le Polynome de sortie n'est pas initialise).

    Les resultats ci-dessus sont les memes avec cette version de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Polynome Polynome::operator = (const Polynome &Q) //A refaire
    {
    	/*Degre=Q.Degre;
    	Coefficients= new double[Q.Degre];
    	for (int i=0; i<Q.Degre; i++)
    	{
    		Coefficients[i]=Q.Coefficients[i];
    	}
    	return (*this);
    }
    Par contre, pour le coup des deux fonctions virtuelles qui ont le meme nom, c'est tel quel en noir sur blanc sur le sujet du projet...

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 262
    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 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Si tu avais pris le temps de faire une petite recherche sur l'opérateur d'affectation, tu aurais vu que sa syntaxe est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Polynome & Polynome::operator = (const Polynome &Q)
    et non:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Polynome Polynome::operator = (const Polynome &Q)
    (il faut retourner une référence).

    Par contre, friend n'a absolument rien à voir avec la choucroute ici. Encore une fois, une recherche sur la signification de ce mot clé t'aurais permi de le comprendre par toi-même.

    Ne perds pas patience. Au début ça a l'air super compliqué tout ça, mais il n'y a pas tant de choses que ça à comprendre. Une fois que tu auras assimilé les quelques fondamentaux, ça ira tout seul.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  9. #9
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Je ne sais pas si tu as bien saisi le rôle de l'opérateur d'affectation : il doit modifier l'objet this sur lequel il est appelé (et en retourner une référence, mais finalement ce n'est qu'un détail). Il ne doit pas retourner un nouvel objet égal à Q.

    Par exemple, si on écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Polynome p1, p2;
    p1 = p2;
    ... c'est strictement équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Polynome p1, p2;
    p1.operator=(p2);
    Tu peux tester, ça compile

    C'est ce qu'essaye de te dire ton compilateur : l'opérateur d'affectation doit être une fonction membre (non statique, mais c'est un détail ça aussi).

    J'essaye de ne pas te donner la solution toute faite, mais j'espère que ça t'aide quand même.

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Une fonction amie n'étant pas une fonction de la classe en cours de définition (pas besoin d'être ami avec soi-même), la déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    friend Polynome operator = (const Polynome&);
    dit au compilateur : il existe une fonction libre (i.e. définie en dehors de la classe) qui défini un opérateur=. Or = est un des opérateurs qui ne peut être défini en dehors de la classe mais doit être défini dans la classe. D'où l'erreur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Polynome Polynome::operator = (const Polynome &Q) //A refaire
    {
    	double C[Q.Degre]; // (1)
    	for (int i=0; i<Q.Degre; i++)
    	{
    		C[i]=Q.Coefficients[i];
    	}
    	Polynome R(Q.Degre, C);
    	return R;
    }
    La ligne (1) est illégale en C++. Pour le reste, comme le dit Kalith, cet opérateur ne modifie pas this. Donc ne répond pas à la sémantique de l'opérateur = telle qu'on l'attend. J'ai l'impression que tu as essayé un vague souvenir de l'idiom copy&swap mais ta mémoire t'a joué des tours. Regarde cette entrée de la F.A.Q. pour l'idiom copy&swap et définir correctement ton opérateur =

    Ensuite envois nous ton prof car c'est complètement débile de considérer simultanément que Polynome hérite RacineFonctions et qu'il possède une politique de copie.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut
    Vos dernieres instructions, surtout le dernier post de r0d m'ont mis sur la voie. Effectivement, pas de friend a mettre, et une reference sur Polynome a retourner (c'est ca que je ne savais pas, en fait).

    Merci a tous, vous me depannez une fois de plus !

    PS : Je me permets de ne pas poster la correction de mon code cette fois-ci pour :

    - Eviter que les autres etudiants de ma promo ne copient mon code s'ils le trouvent
    - Eviter de me prendre un zero parce que Compilatio a trouve mon code sur Internet et a cru que je plagiais (je pourrai toujours courir pour prouver que c'est moi qui l'ai fait apres !).

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

Discussions similaires

  1. [PDO] erreur : Fatal error: Call to a member function prepare() on a non-object
    Par destigul dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 28/04/2015, 14h25
  2. Réponses: 3
    Dernier message: 16/02/2013, 17h08
  3. [PDO] Erreur PDO : Call to a member function fetch() on a non-object
    Par numerodix dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 01/03/2010, 17h37
  4. Réponses: 4
    Dernier message: 02/10/2009, 10h12
  5. Réponses: 3
    Dernier message: 25/10/2008, 15h06

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