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 :

Référence en membre d'un classe


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut Référence en membre d'un classe
    Bonjour.

    Dans un projet, j'ai trouvé des classes utilisant des références pour ses membres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class foo
    {
        bar& m_bar;
        public :
        foo(bar & b):m_bar(b)
        {
        }
    };
    Je serais curieux de savoir ce que vous en pensez et si il existe un réel points positif à utiliser cela.

    Personnellement, je n'en voie pas l'utilité,je trouve que cela permet plus de problème qu'autre chose et je les aurais replacés par des std::shared_ptr.

  2. #2
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Pourquoi utiliser un std::shared_ptr quand on à la garanti que la référence sera valide ?

    Un std::shared_ptr va rendre le code plus dur à relire vu qu'il sous entend que la possession de l'objet est partagée alors qu'elle ne l'est pas ici (et, accessoirement, ça peut avoir un impact sur les performances).

  3. #3
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    • Qu'es ce qui peux garantir que la référence sera toujours valide dans le temps? A par le développeur d'origine?
    • Pour le problème de possession partager, on pourrais utiliser un weak_ptr. Cela permettra au moins de savoir si l'objet existe avant de l'utiliser et être sur qu'il ne sera pas détruit pendant son utilisation.
    • Pourquoi un impact sur les performances?



    yan

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Je comprend ton questionnement, car il est vrai que l'on ne sait absolument pas comment sera géré l'objet référencé par le membre.

    Tu as tout à fait raison de dire que "si ca se trouve, la durée de vie de l'objet référencé sera plus petite que celle de l'objet référençant". Mais il est tout à fait possible de garantir par construction (par la conception même de ton projet) que ce ne sera pas le cas.

    A partir du moment où ta conception arrive à donner des garanties sur la durée de vie des différents éléments, cela ne me gène absolument pas de voir l'une des données membres être une référence, car la référence apporte une garantie de non nullité qu'aucun pointeur ne peut apporter.

    De plus, il est peut être bon de voir exactement le contexte dans lequel la classe est créée. Cela s'écarte peut être un peu du contexte de ton exemple, mais, imagine un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /* voici une classe qui est typiquement destinée à être utilisée dans une relation d'héritage */
    template <typename CRTP>
    class Interface{
    protected:
         Interface(CRTP /* const*/ &ref):derived_{refà}{}
         ~Interface() = default;
    private:
        CRTP /* const */ & derived_; /* permet de récupérer directement le bon objet
                                     * dans les fonction membres de Interface
                                     */
    };
    Dans ce genre de contexte, il n'y a aucun doute : la conception nous donne la garantie que l'objet référencé existera bel et bien tant que l'objet référençant existe. Où serait le besoin de recourir à un pointeur, qu'il soit intelligent ou non

    Du coup, même si j'avoue que cela fait un peu "réponse de normand", je dirais que... cela dépend. De plein de choses, et seul le projet peut nous permettre de juger si c'est "une bonne idée" ou non !!!
    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

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par koala01 Voir le message
    car la référence apporte une garantie de non nullité qu'aucun pointeur ne peut apporter.
    Entre un pointeur null et une référence sur un objet détruit... J'ai rien contre les références, au contraire, mais pour des fonctions.

    imagine un code proche de
    comment tu utilise cette classe??

    Citation Envoyé par koala01 Voir le message
    Du coup, même si j'avoue que cela fait un peu "réponse de normand", je dirais que... cela dépend. De plein de choses, et seul le projet peut nous permettre de juger si c'est "une bonne idée" ou non !!!
    On peux toujours trouver des cas où cela marchera. Mais d'un points de vue maintenabilité ou d'architecture logiciel, je ne voie aucun avantage. Après, il y as peut être quelques avantages intéressant qui permet de résoudre un problème précis, d'où la question

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par yan Voir le message
    Entre un pointeur null et une référence sur un objet détruit... J'ai rien contre les références, au contraire, mais pour des fonctions.
    Comme je te l'ai dit, tout dépend du contexte...

    Imagine une application qui suivrait à peu près le raisonnement suivant :
    1. lire le fichier X pour remplir une liste A
    2. lire le fichier Y pour remplir une liste B d'objet prenant en référence un objet de la liste A
    3. faire ce qu'il y a à faire
    4. vider la liste B
    5. vider la liste A
    6. reprendre au début

    La liste A pourrait parfaitement être des ressources, comme des textures, des modélisations d'objets ou va savoir quoi et liste B une série d'objets à manipuler, la boucle tournant sur un "niveau de jeu", par exemple.

    Dans un tel contexte, tu a la garantie par conception et par construction que les objets référencés par ceux qui se trouvent dans la liste B auront une durée de vie (très légèrement) plus grande que les objets qui les référencent, et donc, qu'il n'y aura jamais le moindre problème
    comment tu utilise cette classe??
    En utilisant le CRTP, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MaClasse : public Interface<MaClasse>{
    public:
        MaClasse(/*paramètres*/):Interface<MaClasse>(*this)/*, membres propres à MaClasse*/{}
        /* ... */
    };
    Ca a l'air bizarre, je sais, mais ca fonctionne parfaitement, et permet même le cas échéant aux fonctions membre de Interface de profiter du polymorphisme au sujet de la classe dérivée
    On peux toujours trouver des cas où cela marchera. Mais d'un points de vue maintenabilité ou d'architecture logiciel, je ne voie aucun avantage. Après, il y as peut être quelques avantages intéressant qui permet de résoudre un problème précis, d'où la question
    Comme je te l'ai dit plus tôt, tant que tu as la garantie que les objets référencés ont une durée de vie supérieure à celles des objets référent, cela ne pose pas plus de problème de maintenabilité que les pointeurs; qu'ils soient intelligents ou non. Avec l'avantage de la non nullité des références

    Donc, oui, je conçois parfaitement que tu t'interroges sur cette construction bizarre, et seule la connaissance du projet dans lequel tu l'as rencontrée pourra te confirmer qu'elle ne pose aucun problème, mais elle ne me choque pas à partir du moment où les garanties sont apportées par construction

    Tu sais, cette discussion me fait un peu penser à toutes celles que l'on a déjà eues (pas forcément toi et moi, mais sur le forum en général ) au sujet du singleton dans lesquelles on dit et répète que le meilleur moyen pour s'assurer qu'un objet ne soit construit qu'une seule fois est encore de s'assurer de n'en créer qu'une seule instance à un point bien particulier.

    La seule différence ici, c'est que le meilleur moyen de s'assurer qu'il n'y aura pas de problème est de s'assurer que, quoi qu'il arrive, les objets référencés soient détruits après les objets référençants... Mais, à partir du moment où cette garantie est présente, il n'y a aucune raison pour qu'il n'y ait le moindre problème
    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

  7. #7
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Citation Envoyé par yan Voir le message
    Qu'es ce qui peux garantir que la référence sera toujours valide dans le temps? A par le développeur d'origine?
    Certaines constructions t'offrent cette garantie, sinon faut faire confiance au dev.

    Citation Envoyé par yan Voir le message
    Entre un pointeur null et une référence sur un objet détruit... J'ai rien contre les références, au contraire, mais pour des fonctions.
    C'est un exemple de construction qui te garanti que la ref sera valide.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(Bar & bar) {
       // pas de problèmes de ref détruite ici dans un contexte mono-thread
       // dans un contexte multi-threads il faut quand même s'assurer qu'un autre thread ne détruira pas "bar"
    }
    Citation Envoyé par yan Voir le message
    Pour le problème de possession partager, on pourrais utiliser un weak_ptr. Cela permettra au moins de savoir si l'objet existe avant de l'utiliser et être sur qu'il ne sera pas détruit pendant son utilisation.
    Si l'objet est partagé, oui, le couple std::shared_ptr / std::weak_ptr fait le boulot.

    Citation Envoyé par yan Voir le message
    Pourquoi un impact sur les performances?
    Un std::shared_ptr compte les références sur l'objet pour le garder en vie tant qu'il reste au moins 1 ref, le comptage de références c'est pas gratuit.

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

Discussions similaires

  1. Initialiser une référence membre d'une classe
    Par NicolasJolet dans le forum C++
    Réponses: 2
    Dernier message: 18/03/2006, 12h14
  2. [VB.NET]Reflexion lister les membres d'une classe ...presque
    Par lucie.houel dans le forum ASP.NET
    Réponses: 19
    Dernier message: 20/09/2005, 13h49
  3. Réponses: 3
    Dernier message: 24/04/2005, 14h19
  4. pointeur membre static de classe
    Par Ca$ul dans le forum C++
    Réponses: 3
    Dernier message: 26/08/2004, 13h02
  5. Thread avec une fonction membre d'une classe
    Par SteelBox dans le forum Windows
    Réponses: 6
    Dernier message: 01/03/2004, 01h15

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