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 :

Différence Pointeur Référence.


Sujet :

C++

  1. #41
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    J'utilise très très peu les pointeurs intelligents. Souvent, c'est plutôt par "flemme" (il faut faire chaque delete avant chaque throw ou exception sinon).

    Cependant, j'ai aussi tendance à penser que les pointeurs ne devraient jamais être en dehors d'un objet. Auquel cas, lors de la destruction de l'objet, il y a destruction des pointeurs. En effet, dans quels cas les pointeurs ne doivent-ils pas être encapsulés dans un objet ? Exemple habituel dans un objet :

    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
    class Object
    {
        std::vector<PolymorphicObject*>Obj;
        public :
            //S'il n'y a pas de fonction Clone.
            void AddPolymorphicObject(const PolymorphicObjectDerived1& P)
            {
                Obj.push_back(new PolymorphicObject(P));
            }
            void AddPolymorphicObject(const PolymorphicObjectDerived2& P)
            {
                Obj.push_back(new PolymorphicObject(P));
            }
            ~Object()
            {
                 //On détruit tous les pointeurs de Obj et autre
            }
    };
    Cette classe Object se chargera du reste (proposera les fonction qu'on voudra faire avec le lot d'objet) : l'objectif du polymorphisme est de pouvoir rassembler les classe dérivées dans un même conteneur pour les traiter indifféremment.

    Sans polymorphisme = inutilité des pointeurs alloués (il peut y avoir des pointeurs juste pour avoir des connections entre objets : par exemple un pointeur sur une texture qui sera allouée statiquement ? ou qui sera dans un "Manager"

    Il est cependant vrai que dans des cas très rares on doit utiliser des pointeurs sans polymorphisme : c'est le cas avec la gestion de ressources de tailles variables (mais dans ce cas on utilise un conteneur standard ou maison et le pointeur est encapsulé).

  2. #42
    screetch
    Invité(e)
    Par défaut
    il y a aussi des cas ou la responsibilité est partagée, ca existe c'est rare, mais ca existe.
    Ca ne justifie pas selon moi un pointeur nu!!!

  3. #43
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    il y a aussi des cas ou la responsibilité est partagée, ca existe c'est rare, mais ca existe.
    Je n'ai jamais encore rencontré un cas ou cette responsabilité ne pouvait pas être mieux répartie. Mais mon expérience est faible, donc si tu as un exemple, je suis preneur.

  4. #44
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    D'ailleurs, lors d'une création de classe, je n'utilise jamais (a voir avec la réponse que vous me donnait à la dernière question) de pointeurs dans l'interface publique (hormis pointeur de fonction et iterateur). Au pire, je fait passer l'objet par référence et je prend le pointeur sur l'alias (ce qui revient au même).

    Juste une question, que ce passe t-il si on fait un delete[] au lieu de delete ou vice-versa ?

    Que ce passe t-il lors d'un delete sur quelque chose d'alloué statiquement ? Rien ?

    Est-il viable, dans l'interface publique (afin d'éviter des copies inutiles) de faire : "Si tu me passes un pointeur, tu gères la durée de vie de l'objet" - "Si tu me passes une référence, je le copie (l'objet) et je me charge de la durée de vie de mon pointeur" ?

  5. #45
    screetch
    Invité(e)
    Par défaut
    Là comme ca, je ne suis pas certain, 'ai souvent été contraint d'utiliser des SmartPtr comme des auto_ptr copiables (pour les mettres dans des vecteurs ou autres)
    si je trouve je te dis

  6. #46
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    J'utilise aussi rarement les pointeurs intelligents (autres que boost::scoped_ptr qui est quand même bien pratique ) mais il y a des cas ou je n'ai pas encore trouvé d'autres solution "générique" pour gérer certains objets du système.

    Typiquement : un système d'events buffurisés, traités uniquement lorsqu'on le demande (régulièrement mais pas dés l'envoi de l'event) et où l'event peut potentiellement avoir une sémantique objet.

    Si l'event est en sémantique par valeur, soit, on copie l'event dans le buffer et on le balance quand on veut le traiter.

    Mais si on veut absolument qu'ils soient en sémantique objet - et non copiable donc - alors il faut soit installer une façon de gérer ces events qui peut être compliqué mais peut être très très efficace quand tu connais le context - implémentation spécifique donc.
    Par contre si tu veux faire un système généraliste.... comme j'ai pas encore trouvé de bonne solution générale pour gérer les events dans ce type de design, j'utilise des smart_ptr.

    J'avoue que j'utilise rarement des pointeurs vers resources de manière non-déterministe, comme dit par d'autre avant, puisque souvent on veut savoir quand on fait les manipulations d'allocation/désallocation de resources.

    Finalement, certains smart ptr semble simplement des solutions possible à des problèmes qui ont trop d'inconnus?

  7. #47
    screetch
    Invité(e)
    Par défaut
    je crois comme le disait emmanuel que c'est la facon feignante de le designer.

    Ca peut etre interessant pour libérer un graphe d'objets lorsqu'on ne maitrise pas l'ordre des désallocations, mais dans le même cas ca peut etre tres dangereux puisque l'on peut créer des cycles. Dans ce cas c'est que la propriété des objets a été mal évaluée a mon avis.

  8. #48
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Pas dans un system d'events buffurisés. Il ne pourrait y avoir de cycle que si il était possible de traiter immédiatement les events.

    Ou tu parles d'un autre type de cycle?

  9. #49
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    un système d'events buffurisés, traités uniquement lorsqu'on le demande (régulièrement mais pas dés l'envoi de l'event) et où l'event peut potentiellement avoir une sémantique objet.

    Si l'event est en sémantique par valeur, soit, on copie l'event dans le buffer et on le balance quand on veut le traiter.
    Juste une question, pour toi un event, c'est un std::string ? un ID+void* ?

    C'est juste que j'ai récemment mis au point un système de signaux avec c++0x, et un gros c'est event = std::string + param divers (grâce au variadiques) qui sont transformer en tuple puis void*.
    Un Connect = une fonction du type void(void*) qui est appelée lors de l'évènement. Cette fonction est généré automatiquement via les lambdas donc le passage au void* est invisible.

    Si je comprend bien, tu as :

    => Arrivée d'un évènement (alloué sur le tas) => mise dans un container (mise du pointeur) =>demande d'exécuter les fonctions connectés => appels des fonctions liées à l'évènement puis destruction de l'évènement.

    Sinon c'est que je n'ai rien compris.

  10. #50
    screetch
    Invité(e)
    Par défaut
    Klaim: Non je répondais en particulier a "Finalement, certains smart ptr semble simplement des solutions possible à des problèmes qui ont trop d'inconnus?"
    c'est un peu pour moi dire "on abandonne et on passe aux smart ptr"

  11. #51
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    screetch> Oui parceque si on "généralise" ce type de système d'évents, alors on a trop d'inconnues donc on ne peut plus arriver a des solutions prévisible (sauf smart pointer qui ne fait que référencer des events qui sont préalloués - interdisant peut être d'avoir différents types d'events).

    NoIdea> Dans le cas dont je parle, soit on utilise de l'héritage dynamique et donc on a une classe presque vide de base type Event; soit on utilise des mécanismes (template party!) pour gérer n'importe quel type fourni comme un identifiant d'event. Dans les deux cas, c'est le mélange buffurisés(on doit garder quelque part) + sémantique objet (on part du principe que les events ne sont pas copiables) + généralisation (pour pouvoir réutiliser la solution).

    Il suffit de changer un de ces paramettres pour que ce soit "facile" d'implémenter un système prévisible.

    Pour moi c'est un sacré challenge. Si vous avez une solution que je connais pas, je suis intéréssé. Pour l'instant, pour un système généralisé je préfère utiliser des events copiables, ça règle le problème mais ça implique que celui qui crée de nouveaux types d'events soit bien au courant du fait qu'ils doivent être copiables.

  12. #52
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Je dois dire que je ne comprend pas en quoi ces contraintes ne te permettent pas de simplement faire le delete sur l'event une fois que les fonctions qui lui sont associées sont exécutées.

  13. #53
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Ah oui, j'oubliais : et si tu laisses les observeurs se débrouiller avec l'objet.

    Mais effectivement si tu ne leur permet pas alors c'est plus simple. Malheureusement ya des cas ou c'est plus logique de maintenir l'objet aussi longtemps que possible. Cela dit ça reste rare.

    Maintenant que j'y pense... je ne rencontre même plus ce genre de besoin depuis quelques temps...


    Bon j'ai rien dit alors

  14. #54
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Bon j'ai rien dit alors
    ...Cependant, ce que tu dis n'est pas faux, mais me semble tout de même être un problème de conception.

    Juste au cas ou mes questions seraient passées à la trappe...

    1) Juste une question, que ce passe t-il si on fait un delete[] au lieu de delete ou vice-versa ?

    2) Que ce passe t-il lors d'un delete sur quelque chose d'alloué statiquement ? Rien ?

    3) Est-il viable, dans l'interface publique (afin d'éviter des copies inutiles) de faire : "Si tu me passes un pointeur, tu gères la durée de vie de l'objet" - "Si tu me passes une référence, je le copie (l'objet) et je me charge de la durée de vie de mon pointeur" ?
    Pour le 1), c'est juste que je suis surpris qu'en c++ on fasse la différence alors qu'en c... un simple free suffit dans les 2 cas.

  15. #55
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par screetch Voir le message
    c'est comme ca que je l'utilise et si tu poses la question comme ca, j'avoue pouvoir la retourner et demander: quel gain a utiliser une référence dans ce cas? (par rapport a un pointeur nu). Mis a part la non nullité.
    [HS]Juste une petite remarque sur la forme, il ne me semble pas avoir dit qu'il était préférable d'utiliser une référence à un pointeur (même si globalement ce n'est pas loin de ce que je pense). Donc non tu ne retournes pas la question, tu en poses une autre.[/HS]

    La non-nullité est probablement la propriété la plus intéressante.
    Je trouve également que l'utilisation de smart pointeur ici a un côté un peu "tout ça pour ça !". Tu crées un smart pointeur avec toute la gestion de la durée de vie (par comptage de référence ou autre), avec une politique de copie, de transfert et partage de la responsabilité, etc. alors que tu n'as besoin de rien de tout ça.

    En rentrant dans des cas beaucoup plus particuliers:
    • Le léger overhead introduit par les smart pointeurs peut être pénalisant dans de très rare cas.
    • Globalement les références sont mieux supportés que les smart pointeurs dans les compilateurs anciens ou exotiques et sont au niveau langage et non bibliothèque ( que ce soit la SL, boost ou une autre) qui peut ne pas être présente et longue à porter. Ce qui les rendent dans l'ensemble plus portable lorsque tu travailles dans des environnements un tantinet exotiques.



    Citation Envoyé par Emmanuel Deloget Voir le message
    Sur le sujet des pointeurs intelligents : il y a une confusion étrange sur le fait qu'il soient utiles, même en C++ (pas d'offense, screetch, hein ? ). Un pointeur intelligent gère la durée de vie d'une instance à la place du programmeur.

    Plusieurs raisons peuvent pousser à l'adoption de smart pointers:

    1) la flemme : le programmeur n'a pas envie de gérer lui même la durée de vie de son instance. Je comprends tout à fait que la flemme soit à la base même de notre métier, mais il y a peut-être des limites à ne pas dépasser En tout cas, ce n'est pas une bonne raison.

    2) le programmeur n'a pas pris la peine de designer correctement son application, et il n'a pas pu déterminer la durée de vie de l'instance : c'est une erreur de sa part, qu'il cache par une sur-utilisation des pointeurs intelligents. C'est mauvais, très mauvais.

    3) le programmeur n'a aucun moyen de déterminer la durée de vie de l'instance : je n'ai jamais rencontré ce cas, mais je veux bien croire qu'il existe. Avec un bémol toutefois : un programme est censé être prédictif, et par conséquent, démontrable. Dans ce cadre, je ne vois pas bien par quel étrange phénomène le comportement de l'instance deviendrait non prédictif.

    4) le programmeur ne sait pas qui possède l'instance : l'instance est partagée par plusieurs objets, et le programmeur n'a pas défini celui qui en était responsable. Pour pallier à ce défaut, on permet à chacun des objets de détruire l'instance en question dès lors qu'il détecte qu'elle n'est plus utilisée. C'est bancal au mieux, catastrophique (au niveau design) au pire.

    5) la possession évolue : la possession est passée à un objet, puis à un autre, etc. Afin de ne pas avoir à tracer cette possession, on utilise un pointeur intelligent. C'est à la limite de la fainéantise exagérée.
    Il y a un peu de tout ça. C'est essentiellement une simplicité d'utilisation (pas besoin de gérer soi-même à la durée de vie, c'est déléguer au pointeur) qui n'est pas pénalisante dans bien des cas.

  16. #56
    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
    Par défaut
    Salut,
    @screetch : La référence est quand même une précondition portée par le langage dont je trouve dommage de se passer par l'utilisation d'un pointeur.

    @Emmanuel : J'ai vu beaucoup beaucoup de problème de fuite mémoire par l'utilisation d'un pointeur nu dont la propriété était soit disant maîtrisée. Alors même si les smart ptr sont un outil de fainéant (codeur ou designer) ils ont l'avantage de diminuer de façon importante ces problèmes à faible coût. Si on sait conduire correctement, la ceinture de sécurité peut être vue comme optionnelle. Mais dans la vie, on est plus confronté au risque d'accident donc autant la mettre

  17. #57
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    le gros intérêt que je vois dans l'utilisation d'un smart_ptr est l'assurance que ça confère vis à vis des scénarios où une exception est levée mettant hors circuit le code de désalocation du pointeur.

  18. #58
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par guillaume07 Voir le message
    le gros intérêt que je vois dans l'utilisation d'un smart_ptr est l'assurance que ça confère vis à vis des scénarios où une exception est levée mettant hors circuit le code de désalocation du pointeur.
    Par rapport à un pointeur nu, oui.

    Par rapport à une variable locale (cas cité par Emmanuel concernant l'intérêt du scope pointeur) ou par rapport à une référence lors d'un appel de fonction (sujet initiale de cette enfilade), le smart pointeur n'apporte rien de plus.

    Edit: je parle bien entendu ici uniquement en terme d'exception safety.

  19. #59
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    Citation Envoyé par gl Voir le message
    Par rapport à un pointeur nu, oui.

    Par rapport à une variable locale (cas cité par Emmanuel concernant l'intérêt du scope pointeur) ou par rapport à une référence lors d'un appel de fonction (sujet initiale de cette enfilade), le smart pointeur n'apporte rien de plus.
    si une fonction return un new l'auto_ptr peut être judicieusement utilisé comme design, non ?

  20. #60
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par guillaume07 Voir le message
    si une fonction return un new l'auto_ptr peut être judicieusement utilisé comme design, non ?
    Oui peut être. Ou pas. Avec aussi peu de détail, il est difficile de se faire un avis. D'autant que l'auto_ptr est quand même bien casse-gueule (au moins dans sa version actuelle).

    Mais quel est le rapport de cette question avec mon message précédent que tu cites ?

Discussions similaires

  1. Equivalent pointeur - référence
    Par MAX-k dans le forum C#
    Réponses: 2
    Dernier message: 24/02/2010, 13h27
  2. Réponses: 6
    Dernier message: 06/03/2009, 06h44
  3. Différence entre référence et pointeur ?
    Par Vivian Pennel dans le forum Langage
    Réponses: 3
    Dernier message: 03/08/2007, 17h19
  4. [pointeurs/référence]
    Par poukill dans le forum C++
    Réponses: 18
    Dernier message: 10/05/2006, 11h49
  5. Réponses: 8
    Dernier message: 26/08/2004, 18h59

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