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

Langage C++ Discussion :

Est-ce idiot de passer un pointeur par référence ?


Sujet :

Langage C++

  1. #1
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut Est-ce idiot de passer un pointeur par référence ?
    Bonjour, ma question est simple :
    Y-a-t'il une différence entre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(int* v);
    // ...
    int* x;
    foo(x);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(int &v);
    // ...
    int x;
    foo(*x);
    ?

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 642
    Points
    7 642
    Par défaut
    Aucun des exemples ne passe un pointeur par référence!
    Le premier passe un pointeur par valeur.
    Le second utilise une l-reférence (et il ne faut pas utiliser d'étoile à l'appel)

    Un pointeur référence, c'est cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int a;
    void fct( int*& r ) {  // passage par référence d'un pointeur
       r = &a;
    }
    int main() {
       int *x;             // pointeur pas encore initialisé
       fct( x );
       assert( x == &a );  // le pointeur pointe bien sur a
    }

  3. #3
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(truc &v);
    // ...
    truc* x;
    foo(*x);
    Pardon, je voulais écrire ça pour le 2e cas.
    Comme ça je peux utiliser truc.machin() au lieu de truc->machin() dans la fonction foo.

    Ça fonctionne correctement mais j'ai l'impression que c'est ultra stupide de faire comme ça

  4. #4
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 313
    Points
    313
    Par défaut
    Intéressant

    Je vais bientôt refaire du C/C++

    Il n'y avait pas de différences réellement entre les pointeurs et les références ? Sûr ? Il me semble pourtant, c'est pas qu'une question de confort, il aurait pas fait ça ? Si ?

  5. #5
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 642
    Points
    7 642
    Par défaut
    Les pointeurs et mes références sont deux principes différents.
    • Le pointeur est une variable qui peut en désigner une autre.
      Un pointeur peut ne rien désigner (pointeur nul) et peut changer de valeur pour désigner autre chose. On peut pointer sur un pointeur ou avoir un tableau de pointeurs ou les référencer.
    • Une référence c'est un alias vers une variable.
      Elle est associée à toujours la même variable et ne correspond jamais à nul. On ne peut pas pointer sur une référence, référencer une référence ou les mettre en tableau.
      On distingue les l-références qui référencent une l-value (donc une variable ou une allocation du tas) et les r-références qui référencent les temporaires et les x-values.
      Une référence peut "prolonger la vie" d'un temporaire; La temporaire associée à une const l-référence ou à une r-référence ne sera détruite qu'à la fin de vie de la référence.
    On peut donc choisir de passer un paramètre par référence ou son adresse par un pointeur. Les 2 rendent un service similaire dans ce cas. On doit normalement préférer l'utilisation de la référence à celui d'un pointeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Objet fct();
    void fct2( Objet const& );
    void fct3( Objet const* );
    {  Objet const& x = fct(); // La fct a retourné un 1er objet, x le référence
        fct2( fct() );         // La fct a retourné un 2nd objet qui est détruit dès le retour de fct2() 
        fct3( &fct() );        // impossible!!
        fct3( &x );            // Ok, on transmet un pointeur sur 1er objet
       ...
    }             // x est détruite, Le 1er objet est détruit

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Matthieu76 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(truc &v);
    // ...
    truc* x;
    foo(*x);
    Pardon, je voulais écrire ça pour le 2e cas.
    Comme ça je peux utiliser truc.machin() au lieu de truc->machin() dans la fonction foo.

    Ça fonctionne correctement mais j'ai l'impression que c'est ultra stupide de faire comme ça
    Si tu espères passer un pointeur par référence, il faut commencer par l'écrire.
    Là tu as... une référence. Où vois-tu un pointeur dans ta signature ?
    void foo(truc* &v);
    Et à moins que ta fonction modifie le pointeur (et non que les données pointées), oui ça n'a aucun intérêt.
    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.

  7. #7
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par Matthieu76 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(truc &v);
    // ...
    truc* x;
    foo(*x);
    Pardon, je voulais écrire ça pour le 2e cas.
    Comme ça je peux utiliser truc.machin() au lieu de truc->machin() dans la fonction foo.

    Ça fonctionne correctement mais j'ai l'impression que c'est ultra stupide de faire comme ça
    Au contraire. C'est très intelligent: tu affirmes depuis la fonction appellée "Tu DOIS me passer un truc valide". Il te manque toutefois une vérification depuis la fonction appelante.

    Dit autrement, les codes clients valides (à supposer que tu partes d'un pointeur) sont:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // truc *x = ...
     
    // soit 1:
    assert(x && "Ouhla! ce n'est pas censé se produire ce truc!!"); // si tu sais que la nullité n'a pas de sens
    foo(*x);
    // C'est un cas à rapprocher de 
    // gsl::non_null<truc> x = ... // Cf les C++ Core Guidelines et GSL
     
     
    // soit 2:
    // si tu sais que la validité de x est liée à une entrée externe que tu ne peux pas controler et que tu ne pourras pas connaitre avant l'exécution
    if (!x) throw std::runtime_error("entrée utilisateur non valide");
    foo(x);

    Mais on peut aussi partir de valeurs optionnelles (C++17)

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::optional<truc> x = ...;
    if (x) foo(*x);

    Tu peux te reférer à mes 3 billets sur la programmation par contrat en C et C++. Les deux premiers ont été republiés sur dvpz -- j'ai de la relecture à faire avant de faire pareil avec le 3e.

    Citation Envoyé par survivals Voir le message
    Il n'y avait pas de différences réellement entre les pointeurs et les références ? Sûr ? Il me semble pourtant, c'est pas qu'une question de confort, il aurait pas fait ça ? Si ?
    Il y a une différence côté invariants: avec une référence que tu affirmes que ce n'est pas censé être nul donc. C'est plus qu'une simple question de confort.

    Après, techniquement parlant, dans le cas des variables, avec une référence, il y a plus de chances que le compilateur dégage la variable qu'avec un pointeur.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int a = 42;
    int &j = a; // aucune chance d'avoir une existance propre
     
    int *p = a; // aura une existance propre en debug, en release, je ne saurai dire
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Après, si ta question est "Est-il idiot de passé un pointé par référence?", la réponse est non.

    Un pointeur et une référence remplissent un rôle similaire: désigner quelque chose.
    Le pointeur est comme un panneau, tu peux le changer de direction, mais il faut aller à la destination pour y trouver la chose.
    La référence est plus comme un hologramme du désigné, tu ne peux pas changer ce qui est reproduit, mais tu n'as pas besoin d'aller le chercher.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

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

Discussions similaires

  1. [PowerShell] Comment passer une string "par référence" dans une fonction ?
    Par Plageman dans le forum Scripts/Batch
    Réponses: 7
    Dernier message: 11/11/2010, 15h01
  2. Transmission de pointeur par référence
    Par bertry dans le forum Débuter
    Réponses: 3
    Dernier message: 06/10/2008, 17h45
  3. Est-il possible de passer des paramètres par référence en VB 6 ?
    Par beegees dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 21/09/2008, 14h02
  4. passer une variable par référence
    Par roblescriso dans le forum Requêtes et SQL.
    Réponses: 0
    Dernier message: 04/04/2008, 17h05
  5. [JACOB] Comment passer un objet par référence à une méthode
    Par zlavock dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 21/03/2005, 18h28

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