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 :

remplacer un pointeur brut par un pointeur intelligent (ou pas)


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut remplacer un pointeur brut par un pointeur intelligent (ou pas)
    Bonjour,

    j'ai récemment choisi de modifier le code d'un de mes projets en remplaçant un pointeur sur une donnée qui tient une place importante dedans, par un pointeur intelligent, à force d'entendre que les pointeurs bruts sont à éviter tant que possible, au profit des smarts pointer, pour plus de sécurité (à défaut de l'avoir entendu, j'en ai l'impression).

    Plus concrètement :
    • j'ai plusieurs objets (disons 5) dans un vector
    • un pointeur qui pointe tour à tour sur ces 5 objets


    Du coup :
    • shared_ptr : inadapté (qu'un seul pointeur pour plusieurs objets)
    • unique_ptr : inadapté (sauf si on peut éviter qu'il ne détruise mes objets à chaque (ré)affectation)
    • weak_ptr : je ne vois pas trop sa particularité mais je le penses inadapté
    • * : au final ça me parait être le plus adapté, mais on entends souvent parler du manque de sureté de sa manipulation alors bon...


    qu'en pensez-vous ?

    Merci.

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Euh... pourquoi ne pas simplement utiliser un itérateur ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    std::vector<int> v(5);
    for (auto it=v.begin(), itEnd=v.end(); it!=itEnd; it++)
    {
        cout << *it << endl;
    }

  3. #3
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    Citation Envoyé par cob59 Voir le message
    Euh... pourquoi ne pas simplement utiliser un itérateur ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    std::vector<int> v(5);
    for (auto it=v.begin(), itEnd=v.end(); it!=itEnd; it++)
    {
        cout << *it << endl;
    }
    Parce que le vector est une donnée membre (private) d'une classe A, que je parcours dans une classe B.

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    Parce que le vector est une donnée membre (private) d'une classe A, que je parcours dans une classe B.
    Alors ajoute des méthodes pour accéder à/utiliser ton vecteur.

  5. #5
    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
    Bonjour,

    si tu utilises ton pointeur juste comme allias sur une entrée particulière de ton vector, l'idéal est peut-être un simple * effectivement (d'après ce que j'ai lu/compris du GotW 104 à ce sujet). Tu peux le const*er (sisi ça existe ! - const*) pour t'assurer de ne pas y toucher pour "plus de sécurité", voire le *conster (*const) pour t'assurer de ne pas changer d'objet en cours de route.
    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.

  6. #6
    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
    Je pense que tu ne prends pas le problème dans le bon sens. Il faut regarder non pas le pointeur, mais l'objet. La question n'est pas : Comment remplacer tel pointeur par tel pointeur intelligent, mais plutôt comment je vais gérer la durée de vie de l'objet.

    Ainsi, dans ton cas, si ton vecteur contient directement des objets (et pas des pointeurs), leur durée de vie est déjà gérée, et un simple pointeur ailleurs dans le code est satisfaisant (éventuellement un non_owning_ptr... voir ma réponse au GotW).

    Si ton vecteur contient des pointeurs, mais qu'il reste seul possesseur des objets, tu as alors un vector<unique_ptr<T>> et tu peux encore utiliser un pointeur nu pour références ces objets depuis ailleurs.

    Si ces objets peuvent continuer d'exister même si le vecteur est détruit, tu as une propriété partagée, et un vector<shared_ptr<T>>. Et là selon que ton pointeur fasse ou pas partie des personnes qui peuvent prolonger cette durée de vie, c'est à dire qui possède en copropriété l'objet, tu choisiras un shared_ptr ou un weak_ptr.

    Dans tous les cas, tu remarquera qu'il n'y a plus de delete explicite dans le code. Ce qui est l'objectif premier des smart pointers.
    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.

  7. #7
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je pense que tu ne prends pas le problème dans le bon sens. Il faut regarder non pas le pointeur, mais l'objet. La question n'est pas : Comment remplacer tel pointeur par tel pointeur intelligent, mais plutôt comment je vais gérer la durée de vie de l'objet.

    Ainsi, dans ton cas, si ton vecteur contient directement des objets (et pas des pointeurs), leur durée de vie est déjà gérée, et un simple pointeur ailleurs dans le code est satisfaisant (éventuellement un non_owning_ptr... voir ma réponse au GotW).

    Si ton vecteur contient des pointeurs, mais qu'il reste seul possesseur des objets, tu as alors un vector<unique_ptr<T>> et tu peux encore utiliser un pointeur nu pour références ces objets depuis ailleurs.

    Si ces objets peuvent continuer d'exister même si le vecteur est détruit, tu as une propriété partagée, et un vector<shared_ptr<T>>. Et là selon que ton pointeur fasse ou pas partie des personnes qui peuvent prolonger cette durée de vie, c'est à dire qui possède en copropriété l'objet, tu choisiras un shared_ptr ou un weak_ptr.

    Dans tous les cas, tu remarquera qu'il n'y a plus de delete explicite dans le code. Ce qui est l'objectif premier des smart pointers.
    merci pour cette réponse. C'est vrai que mon raisonnement est assez "j'utilise des pointeurs intelligents pour utiliser des pointeurs intelligents", je n'avais pas réfléchi en terme de durée de vie, sinon j'aurais éviter mes petits ennuis avec mon unique_ptr.

    Je suis dans le premier cas dont vous parlez. Je vais donc aller voir votre réponse (même toute la discussion) au GotW(104 si j'ai bien suivi l'actualité).

    Un weak_ptr sur un objet n'assure pas sa durée de vie donc ? est-ce qu'il est détruit (le pointeur) si plus d'objet à pointer ? ou il est mit à nullptr (pour savoir comment il faut le gérer) ?

  8. #8
    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 Kaamui Voir le message
    Un weak_ptr sur un objet n'assure pas sa durée de vie donc ? est-ce qu'il est détruit (le pointeur) si plus d'objet à pointer ? ou il est mit à nullptr (pour savoir comment il faut le gérer) ?
    Non, il ne prolonge pas le durée de vie. Est-ce que tu as lu mon tutoriel sur ce sujet ? http://loic-joly.developpez.com/tuto...mart-pointers/

    En gros, au moment où tu veux accéder à l'objet pointé, il vérifie si ce dernier existe toujours, et si ce n'est pas le cas t'en averti, à toi d'en tenir compte.
    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.

  9. #9
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Bonjour,

    si tu utilises ton pointeur juste comme allias sur une entrée particulière de ton vector, l'idéal est peut-être un simple * effectivement (d'après ce que j'ai lu/compris du GotW 104 à ce sujet). Tu peux le const*er (sisi ça existe ! - const*) pour t'assurer de ne pas y toucher pour "plus de sécurité", voire le *conster (*const) pour t'assurer de ne pas changer d'objet en cours de route.
    je ne suis pas sur de ce que veut dire "alias sur une entrée particulière de ton vector", mais si ça veut dire ce que je penses, alors tu as tout à fait compris de quoi il s'agissait.

    Donc je penses en effet qu'il va falloir que j'utilise un pointeur classique, mais ça m'embête... pour les const je vais réfléchir aux constéquences (sisi j'ai osé faire cette blague minable ). Je ne souhaites pas que mon pointeur puisse être modifié (mais qu'il change d'objet pointé) et je ne veux pas non plus que mes objets soient modifiés.

  10. #10
    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 Kaamui Voir le message
    je ne suis pas sur de ce que veut dire "alias sur une entrée particulière de ton vector", mais si ça veut dire ce que je penses, alors tu as tout à fait compris de quoi il s'agissait.

    Donc je penses en effet qu'il va falloir que j'utilise un pointeur classique, mais ça m'embête... pour les const je vais réfléchir aux constéquences (sisi j'ai osé faire cette blague minable ). Je ne souhaites pas que mon pointeur puisse être modifié (mais qu'il change d'objet pointé) et je ne veux pas non plus que mes objets soient modifiés.
    En fait par allias, j'entends... euh ben allias ^^
    Juste une autre variable pour accéder à l'objet, type une fonction MyObject* getObject(index) pour récupérer un pointeur sur l'objet (ou une référence).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MyVec { vector<Obj> vec; const obj* getObj(int index) const { return vec[index]; } };
     
    // utilisation
    {
      // dans ce scope, myObj pointe sur mon objet
      // les différents const assurent que l'objet pointé ne sera jamais modifié
      // ni que l'on changera d'objet pointé en cours de route
      const obj* const myObj = myvec.getObj(i);
    }
    le const* me semble approprié puisque tu ne modifieras pas l'objet.
    le *const c'est pour éviter d'avoir un myobj = un autre objet, arithmétique des pointeurs et autres joyeuseté
    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.

  11. #11
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    Citation Envoyé par Bousk Voir le message
    En fait par allias, j'entends... euh ben allias ^^
    Juste une autre variable pour accéder à l'objet, type une fonction MyObject* getObject(index) pour récupérer un pointeur sur l'objet (ou une référence).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MyVec { vector<Obj> vec; const obj* getObj(int index) const { return vec[index]; } };
     
    // utilisation
    {
      // dans ce scope, myObj pointe sur mon objet
      // les différents const assurent que l'objet pointé ne sera jamais modifié
      // ni que l'on changera d'objet pointé en cours de route
      const obj* const myObj = myvec.getObj(i);
    }
    le const* me semble approprié puisque tu ne modifieras pas l'objet.
    le *const c'est pour éviter d'avoir un myobj = un autre objet, arithmétique des pointeurs et autres joyeuseté
    Tu as raison.

    Merci pour votre aide à tous.
    Sujet résolu.
    @+

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

Discussions similaires

  1. Réponses: 55
    Dernier message: 18/03/2014, 12h11
  2. Pointeurs intelligents vs. pointeurs bruts
    Par Nanoc dans le forum C++
    Réponses: 69
    Dernier message: 29/10/2010, 09h53
  3. Réponses: 3
    Dernier message: 29/07/2008, 09h56
  4. Taille de la mémoire pointée par un pointeur
    Par Tex-Twil dans le forum C
    Réponses: 9
    Dernier message: 09/10/2006, 14h27
  5. Réponses: 3
    Dernier message: 17/03/2006, 14h50

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