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 :

Passage par valeur & passage par r�f�rence


Sujet :

C++

  1. #1
    Membre actif
    Inscrit en
    F�vrier 2008
    Messages
    23
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2008
    Messages : 23
    Par d�faut Passage par valeur & passage par r�f�rence
    Salut � tous,

    j'aimerais bien savoir dans quel cas on est oblig� d'utiliser le passage par r�f�rence et dans quel cas on utilise le passage par valeur ?

  2. #2
    Expert confirm�
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 772
    Par d�faut
    Je vois 2 r�ponses
    • Passage par valeur pour des "Plain Old Data" (POD), par r�f�rence pour les classes
    • Passage par valeur pour les param�tres d'entr�e (pas de modification) et par r�f�rence pour les param�tres de sortie (*) (modification, r�cup�ration de valeur)


    * -> Comme l'a dit leternel, on peut pr�ciser const pour ne pas modifier une r�f�rence.

  3. #3
    Expert �minent

    Femme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    D�tails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par d�faut
    La r�f�rence ne copie pas l'objet.

    Si tu as un objet de 8Mo, tu pr�f�res ne pas le copier pour le passer � une fonction.
    La solution, c'est le passage par r�f�rence (constante : T const&) (ou en C, par pointeur constant)

    L'autre avantage de la r�f�rence, c'est que si elle n'est pas constante (T &), tu peux modifier l'objet utilis� pour l'appel de la fonction.

    C'est comme cela que fonctionne cin >> variable.
    Il s'agit de l'appel de la fonction operator>>(istream&, T&) avec pour argument cin et variable.


    Il y a en fait trois modes de passages de param�tres:
    1. par valeur
    2. par r�f�rence constante
    3. par r�f�rence modifiante

    A cela s'ajoute le probl�me du pointeur, mais en C++, tu ne l'utiliseras pas sans une bonne raison.
    Un pointeur est plus ou moins comme une r�f�rence. (T const& correspondrait � T const&, et T *T &).

    Le plus efficace est le passage par r�f�rence constante, d�s que la variable est plus grosse qu'une r�f�rence (c'est � dire pour quasiment tout objet)
    Ca devrait �tre ton choix par d�faut pour les classes.

    Les autres modes r�pondent � d'autres crit�res.

    Le passage par valeur est satisfaisant quand la variable est petite (un type primitif, ou une std::pair<int, int>, par exemple).
    Il est aussi int�ressant quand on veut explicitement faire une copie de l'argument.
    par exemple, une fonction pourrait prendre un iterateur par copie, pour modifier cette copie en interne, sans modifier l'argument.

    par exemple std::distance pourrait �tre impl�ment� ainsi:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    "unsigned int" distance( InputIt first, InputIt const& last) {
        unsigned int d = 0;
        while ((first++)!=last) d++;
        return d;
    }
    Comme les compilateurs peuvent faire ce qu'ils veulent tant que "tout se passe comme si" ils avaient fait comme tu demandes, tu peux m�me toujours passer une r�f�rence constante plutot qu'une copie.

    int f(int i) {return i;} et int f(int const& i) {return i;} devrait �tre compil�es de la m�me mani�re.
    Je pr�f�re cependant la premi�re car elle est plus l�g�re � lire.

    La r�f�rence modifiante correspond en g�n�ral � une valeur de retour ou un contexte � modifier.
    si je reprends les operateurs >> de cin, tu as la forme complete suivante:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    std::istream& operator>>(std istream& stream, Type & variable) {
        //...modifier variable avec cin
        return stream;
    }

  4. #4
    Membre tr�s actif

    Homme Profil pro
    �tudiant
    Inscrit en
    Juillet 2014
    Messages
    103
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 33
    Localisation : France, Essonne (�le de France)

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

    Informations forums :
    Inscription : Juillet 2014
    Messages : 103
    Par d�faut
    Salut,

    Lorsqu'un objet est pass� par r�f�rence � une fonction, elle travaille directement sur l'objet qui a lui a �t� fourni : tous les traitements que la fonction fait subir � l'objet seront effectifs m�me apr�s la fin de ta fonction.

    Lorsqu'un objet est pass� par valeur � une fonction, l'objet est copi� au pr�alable et c'est sur cette copie que ta fonction va travailler. En cons�quence, l'objet que tu passes � ta fonction ne sera pas modifi� par tes traitements.

    En gros, si on r�sume dans quels cas tu dois utiliser l'une ou l'autre des techniques :

    Passage par r�f�rence :
    • Tu veux �viter de recopier l'objet pass� en argument (ce qui peut alt�rer les performances du programme en fonction de la taille de l'objet)
    • Tu veux que l'objet pass� en argument soit modifi� directement par les traitements de ta fonction


    Passage par copie :
    • Tu ne veux pas que l'objet pass� en argument soit modifi�


    J'esp�re avoir �t� clair et ne pas avoir dit de b�tise !

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    D�tails du profil
    Informations personnelles :
    Localisation : France, Paris (�le de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par d�faut
    Citation Envoy� par Jimmy91 Voir le message
    Passage par copie :
    • Tu ne veux pas que l'objet pass� en argument soit modifi�
    Ca c'est une b�tise, pour que l'objet ne soit pas modifi�, c'est const qu'on utilise.

    Aujourd'hui, le passage par valeur en C++ moderne ne se justifie dans presque aucun cas. Il est tol�rable pour les types primitifs. Sinon, j'applique les r�gles suivantes :

    Passage par r�f�rence (l-value-reference):
    • non constante si l'appel� doit modifier ou stocker une r�f�rence vers l'objet
    • constante dans tous les autres cas

    Passage par r-value-reference quand la propri�t� de l'objet doit �tre confi�e � l'appel�.

    Le fait que la fonction appel�e copie l'objet pass� en argument est toujours possible avec une r�f�rence constante si l'objet est copiable, et devrait rester un d�tail d'impl�mentation. Si tu dois retenir une chose, une seule : exit le passage par valeur sauf pour les types primitifs de petite taille.

  6. #6
    Membre tr�s actif

    Homme Profil pro
    �tudiant
    Inscrit en
    Juillet 2014
    Messages
    103
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 33
    Localisation : France, Essonne (�le de France)

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

    Informations forums :
    Inscription : Juillet 2014
    Messages : 103
    Par d�faut
    Citation Envoy� par jblecanard Voir le message
    Ca c'est une b�tise, pour que l'objet ne soit pas modifi�, c'est const qu'on utilise.
    Merci pour cette correction ! Au temps pour moi, je n'avais pas pens� au passage par r�f�rence constante.

  7. #7
    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
    Le passage par valeur est aussi utile dans une impl�mentation de l'idiome copy-and-swap (o� une copie est de toute fa�on n�cessaire), car il permet d'�viter une copie inutile dans certains cas.
    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.

  8. #8
    R�dacteur/Mod�rateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : Canada

    Informations professionnelles :
    Activit� : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par d�faut
    Le passage par valeur sur autre chose qu'un type natif ou pointeur, tu devrais en avoir tr�s peu, voire aucun.
    Le seul moment o� tu passeras par valeur c'est justement parce que ta fonction a besoin de modifier une copie du param�tre. Et m�me dans ce cas, il sera souvent plus clair pour tous de d�clarer le param�tre const& et faire une copie effectivement � l'int�rieur.
    Pensez � consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation r�seau ?
    Aucune aide via MP ne sera dispens�e. Merci d'utiliser les forums pr�vus � cet effet.

  9. #9
    Membre actif
    Inscrit en
    F�vrier 2008
    Messages
    23
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2008
    Messages : 23
    Par d�faut
    Citation Envoy� par Bousk Voir le message
    Le passage par valeur sur autre chose qu'un type natif ou pointeur, tu devrais en avoir tr�s peu, voire aucun.
    Le seul moment o� tu passeras par valeur c'est justement parce que ta fonction a besoin de modifier une copie du param�tre. Et m�me dans ce cas, il sera souvent plus clair pour tous de d�clarer le param�tre const& et faire une copie effectivement � l'int�rieur.
    Si par exemple on a :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    void incr(int &a)  //ça marchera jamais si la variable a n'est pas passée en référence lors de l'appel 
    {
        a++;
    }
    hors que dans ce qui suit (la fonction pgcd)
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int pgcd(int a, int b)   //aucun paramètre n'est passé en référence et ça marche lors de l'appel de la fonction en main() 
     {  int r;
       while (b != 0)
         {
              r = a%b ;
             a = b;
             b = r;
         }
         return a ;
    }

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    D�tails du profil
    Informations personnelles :
    Localisation : France, Paris (�le de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par d�faut
    Et donc, en quoi les propos de bousk contredisent-t-ils tes examples maiza_med ?

  11. #11
    Membre actif
    Inscrit en
    F�vrier 2008
    Messages
    23
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2008
    Messages : 23
    Par d�faut
    Citation Envoy� par jblecanard Voir le message
    Et donc, en quoi les propos de bousk contredisent-t-ils tes examples maiza_med ?
    J'voulais juste savoir pourquoi �a a march� pour la fonction PGCD(sans utiliser le &) pourtant notre fonction � modifier les param�tres ???

  12. #12
    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
    Non, elle modifie une copie des param�tres. Dans l'appelant, les valeurs pass�es pour a et b n'ont pas chang�.
    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.

  13. #13
    Membre actif
    Inscrit en
    F�vrier 2008
    Messages
    23
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2008
    Messages : 23
    Par d�faut
    Citation Envoy� par M�dinoc Voir le message
    Non, elle modifie une copie des param�tres. Dans l'appelant, les valeurs pass�es pour a et b n'ont pas chang�.
    En faite j'ai compar� les changements des param�tres de la fonction pgcd avec la fonction permut o� le contenu sera chang� :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    void permut(int &x, int &y)
                { int z;
                z=y;
                y=x;
                x=z;
                }

  14. #14
    R�dacteur/Mod�rateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : Canada

    Informations professionnelles :
    Activit� : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par d�faut
    Citation Envoy� par maiza_med Voir le message
    Et j'ai constat� aussi que le passage par r�f�rence est utilis� beaucoup plus pour les proc�dure (void) dont on a pas un r�sultat (return) ????
    Mis � part que tu confonds tout et que �a n'a aucun rapport, je ne vois pas o� tu esp�res en venir avec tes "exemples" ou cette phrase.
    Passer les param�tres par r�f�rences pour les modifier, c'est un peu la base... et je vois pas ce que le type de retour vient faire l�-dedans ?
    Tu veux modifier un param�tre ? Tu utilises une r�f�rence ou un pointeur. Tu veux retourner une valeur ? Tu retournes une valeur... (captain obvious inside)
    Tu veux faire les 2 ? Fais les 2! Ce sont juste 2 choses compl�tement orthogonales. Exemple, au hasard, une fonction bool Find(T* p).
    En plus ce terme de proc�dure, �a fait un moment que je l'ai pas entendu, surtout en C++.

    Btw, la copie ou const& est �galement le seul moyen de passer des lit�raux � une fonction. L� o� une r�f�rence exigera d'utiliser une vraie variable.
    Pensez � consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation r�seau ?
    Aucune aide via MP ne sera dispens�e. Merci d'utiliser les forums pr�vus � cet effet.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 6
    Dernier message: 20/01/2013, 14h08
  2. R�ponses: 6
    Dernier message: 18/05/2012, 12h07
  3. R�ponses: 2
    Dernier message: 15/06/2011, 11h13
  4. R�ponses: 12
    Dernier message: 26/01/2008, 20h23
  5. Passage par r�f�rence et non pas par valeur
    Par GPZ{^_^} dans le forum Flash
    R�ponses: 2
    Dernier message: 14/05/2007, 15h21

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