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 :

Accesseur / Mutateur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 3
    Par défaut Accesseur / Mutateur
    Bonjour,

    Voila je suis nouveau sur le forum, j'ai épluché un peu le site à la recherche d'infos sur ce sujet, j'ai obtenu des infos intéressantes mais des questions subsistes.

    Voici un petit exemple qui illustre mes interrogations :
    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 CRoue
    {
    private:
        float m_fDiametre;
    public:
        const float & GetDiametre() const;
        void SetDiametre(cont float & fDiametre);
    }
     
    class CVoiture
    {
    private:
        CRoue m_roue;
     
    public:
        const CRoue & GetRoue() const;
    }
    peut on remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const float & GetRoue() const;
    par :
    ainsi on peut appliquer le mutateur SetDiametre() directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void main()
    {
        CVoiture voiture;
        voiture.GetRoue().SetDiametre(500.0);
    }
    Ou faut il garder :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const float & GetRoue() const;
    et créer le mutateur du diamètre de la roue directement dans la classe CVoiture? :
    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
    19
    20
    21
     
    class CVoiture
    {
    private:
        CRoue m_roue;
     
    public:
        const CRoue & GetRoue() const;
        void SetDiametreRoue(const float & fDiametre);
    }
     
    void CVoiture::SetDiametreRoue(const float & fDiametre)
    {
        this->m_roue.SetDiametre(fDiametre);
    }
     
    void main()
    {
        CVoiture voiture;
        voiture.SetDiametreRoue(500.0);
    }
    Un accesseur n'est pas censé modifier la donnée qu'il retourne mais peut il retourner un pointeur sur cette donnée pour que celle ci soit modifiée?
    Sinon, doit on développer des mutateurs dans chaque classe contenant l'objet à modifier (ex : SetDiametre() et SetDiametreRoue() un mutateur par classe) ? Ceci alourdit le code, y'a t'il une autre solution?

    Voila, j'espère avoir été clair
    Merci d'avance

  2. #2
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 295
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 295
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    pour ma part, je pense que c'est une question presque philosophique, et au moins sémantique. Je m'explique:
    Si une fonction porte le nom GetX(), cela signifie: donne-moi la valeur de la variable x, étant sous-entendu que c'est seulement pour connaitre cette variable, et non dans le but de la modifier. En effet, si on veut modifier cette variable, on utilsera plutot un modificateur (setter) du style: SetX( float nouvelle_valeur );

    Enfin, si tu souhaites que ta variable membre x puisse être modifiée par "tout le monde", alors pourquoi ne pas directement la mettre en public? Certes cela rompt l'encapsulation, mais ce n'est pas forcément mal, et puis de toutes façons, si tu as un accesseur qui renvoie une référence non constante vers cet objet, cela rompt également l'encapsulation.

    C'est mon point de vue. Moi je n'hésite plus à déclarer en public des variables membre lorsqu'il n'y a pas de raison pour qu'elles ne le soit pas.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Consultant BigData
    Inscrit en
    Juillet 2009
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Consultant BigData

    Informations forums :
    Inscription : Juillet 2009
    Messages : 129
    Par défaut
    Je pense également qu'il s'agit ici plus d'une question de sémantique.

    Ce qu'il faut se poser comme question, c'est "est-ce que ma classe englobante doit avoir connaissance du paramètre de la classe englober ?" J'entend par là que plusieurs méthodes sont à mon avis toutes aussi valables les unes que les autres suivant le contexte.

    Dans ton cas, je trouve que d'ajouter une méthode setDiametreRoue dans CVoiture est une idée tout à fait correcte. Elle va juste englober un appel à m_roue.SetDiametre(...).

    Par contre, enlever le const sur un getter est, de mon point de vue, une pratique à éviter. De façon général, si on demande à obtenir une valeur, on ne demande pas à la modifier.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 3
    Par défaut
    Tout d'abord merci

    Vos réponses m'éclairent un peu sur le sujet, mais je ne peut m'empêcher de penser que d'un côté, si je fait un mutateur sur chaque classe englobante on va atteindre un nombre hallucinant de méthodes dans la classe qui englobe toutes les autres.
    Et d'un autre côté, je me dis que rompre l'encapsulation n'est pas une bonne chose.
    Un compromis entre les deux me pousserais à respecter l'utilisation d'accesseurs et de mutateurs pour les variables membres de types communs, int, float, bool... et mettre les variables membres étant des classes complexes en public.

    J'ai bien retenu la question à se poser :
    est-ce que ma classe englobante doit avoir connaissance du paramètre de la classe englober ?
    La plus part du temps dans mon cas c'est oui, c'est donc peut être dû à un mauvais découpage des classes dès le début de la conception .

    En tout cas merci pour vos réponses

  5. #5
    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 VanLoc Voir le message
    Vos réponses m'éclairent un peu sur le sujet, mais je ne peut m'empêcher de penser que d'un côté, si je fait un mutateur sur chaque classe englobante on va atteindre un nombre hallucinant de méthodes dans la classe qui englobe toutes les autres.
    Et d'un autre côté, je me dis que rompre l'encapsulation n'est pas une bonne chose.
    En mettant des accesseurs/mutateurs sur tous les membres de ta classe (surtout s'ils sont triviaux), tu romps déjà l'encapsulation. Conceptuellement,que tu puisses accéder à tous les membres de ta classe car ils sont public ou car il existe un mutateur sur chacun d'entre eux cela ne change pas grand chose.

    Raisonne sur les services qu'offrent la classe plutôt que sur les données qui la composent.

  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
    Salut,

    Je rejoins gl dans mon approche...

    Normalement, les membres d'une classe devraient surtout être utilisés pour permettre à la classe de rendre les services que l'on attend d'elle...

    Dans le cas présent, il faut te poser la question de savoir quelle service tu attend que ta classe Roue puisse te rendre grâce à son membre diamètre.

    Une chose est sure, c'est que si tu peux effectivement attendre qu'elle soit en mesure de répondre à la question "quel est ton diamètre", il n'y a, a priori, aucune raison de pouvoir le modifier...

    Si tu change le diamètre d'une roue, tu obtiens, purement et simplement, une autre roue
    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

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

Discussions similaires

  1. Intérêt de l'accesseur /mutateur ?
    Par orphee03 dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 30/08/2013, 17h12
  2. [NetBeans 6.9] probleme accesseurs-mutateurs
    Par stc074 dans le forum NetBeans
    Réponses: 0
    Dernier message: 31/10/2010, 16h33
  3. Mutateur et accesseur sur énumération
    Par stallaf dans le forum Débuter
    Réponses: 13
    Dernier message: 17/08/2010, 13h44
  4. [Doc] Mutateurs/Accesseurs PHP5, comment faites vs ?
    Par ePoX dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 4
    Dernier message: 28/02/2006, 01h34
  5. Outils pour creer les accesseurs et les mutateurs
    Par MarieMtl dans le forum MFC
    Réponses: 3
    Dernier message: 03/10/2005, 17h03

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