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 :

Getter/setter ou retour par copie/référence ?


Sujet :

C++

  1. #1
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut Getter/setter ou retour par copie/référence ?
    Salut à toutes et à tous !

    Je voudrais savoir si quelque chose vous choque dans le code suivant :
    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
    22
    class Demography{
     
    public :
     
        N_type pop_size(coord_type const& where, time_type time) const {
        try{
            return populations.at(time).at(where);
        }
        catch(const std::out_of_range& oor){
        return 0.;
        }
    }
     
     
        N_type& pop_size(coord_type const& where, time_type time) {
            return populations[time][where];
        }
     
    private :
         std::map<time_type, std::map<coord_type, N_type> > populations;
     
    }
    J'utilise une version pour modifier l'objet dans une première phase
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Demography demo;
    demo.pop_size(x, t0+1) = round(Ntilde);
    et l'autre version constante pour lire les données qu'il contient dans un contexte où l'objet demo est passé par référence constante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(unsigned int ind=1; ind <= demo.pop_size(x, t0)){ // do something}
    Du coup j'imagine que le compilateur sait à quelle version il a affaire (en tout cas le code marchait), et je suis un peu content quand même parce que l'écriture me semble intuitive (mais ça c'est mon avis de noob à moi ça hein ). Mais on m'a fait remarqué qu'utiliser le même nom pour faire en fait un get ou un set pouvait être une mauvaise idée. Je me doute bien que rien n'est tout noir ou tout blanc... mais votre avis m'intéresse.

    Bien à vous tous, et joyeux printemps

    PS : j'avais vu passer un lien vers un fil de discussion qui abordait ce sujet en long en large et en travers, mais c'était il y a longtemps, je n'avais pas tout compris et je ne le retrouve plus... si quelqu'un sait à quoi mes souvenirs flous sont liés...

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    C'est le fonctionnement des containers de la STL et y'a pas 500 solutions à vrai dire.
    Tu manipules qu'un flottant donc faire un set plus explicite pourrait être plus clair, mais dans le cas d'objets plus complexes il est bien de pouvoir les manipuler directement dans la collection, d'où le retour par référence.
    Y'a même des syntaxes qui permettent d'écrire la version non const à partir de la const. Pour n'avoir à écrire la logique de récupération qu'une seule fois.
    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.

  3. #3
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Ok super !
    Merci pour ta réponse !
    Je prends note pour la syntaxe bizarre le jour où je voudrais repasser dessus !

    A+ !

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    La syntaxe bizarre, c'est de passer par un const_cast pour retirer la constance de la référence retournée.
    Cela ne s'applique bien sûr que si les deux opérateurs sont strictement identiques.

  5. #5
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    De tête ça donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class C {
      const T& get() const { return ... ; }
      T& get() { return const_cast<T&>(static_cast<const C*>(this)->Get()); }
    };
    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
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

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

    De manière générale, il faut prendre le pli de réfléchir à ses classes en tant que "fournisseur de services" et non en termes des données qui les composent. C'est à dire que la première question à se poser lorsque l'on envisage de développer une nouvelle classe devrait être : de quelles fonctions vais-je avoir besoin pour manipuler les données du type en question

    Dans bien des cas, on va se rendre compte que l'on n'a déjà pas besoin des certains accesseurs ( "getter"), parce que les données qui permettent d'implémenter les comportements des fonctions envisagées n'ont, tout simplement, aucun intérêt pour l'utilisateur de la classe.

    Dans quelques rares cas, on se rendra compte que la possibilité de récupérer certaines données membres de la classe correspond effectivement à des services que l'on est en droit d'attendre de sa part et on pourra donc justifier l'apparition d'accesseurs. Dans ce cas, quelque soit le type de retour envisagé, il faudra s'assurer de l'impossibilité de modifier directement la valeur de la donnée membre. Il faudra donc veiller à ce que l'accesseur soit une fonction constante et qu'il renvoie -- selon le cas -- la donnée en question par valeur ou par référence constante.

    Quant aux mutateurs, c'est encore plus simple : on ne devrait JAMAIS les utiliser : la modification d'une donnée membre d'une classe DOIT se faire au travers d'une fonction qui s'occupera (au besoin en déléguant une partie du travail à d'autres fonctions) qui s'occupera de tous les calculs et de toutes le vérifications permettant de s'assurer que la modification demandée est valide et cohérente.

    Ainsi, au lieu d'avoir une fonction setPosition(Position const & newPos), nous aurons (au choix) une fonction move(Position const & newPos) qui s'assurera que newPos correspond à une position valide ou une fonction moveTo(Type diffX, Type diffY /*,Type diffZ*/) qui commencera par calculer la nouvelle position sur base des paramètres reçus et par s'assurer que cette nouvelle position correspond effectivement à une position valide.

    De cette manière, nous pourrons éviter que l'utilisateur de notre classe ne fasse une "monstrueuse connerie" en calculant la nouvelle position d'un objet "à la va te faire foutre"
    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 éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Ce JAMAIS restera à jamais imprimé sur mes globes oculaires.

    Merci de ta réponse !!!

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 21/12/2014, 20h03
  2. Retour par copie et gestion mémoire
    Par dmat4 dans le forum Débuter
    Réponses: 2
    Dernier message: 02/02/2013, 01h00
  3. Réponses: 10
    Dernier message: 20/09/2006, 12h53
  4. Passage par copie vs passage par référence
    Par bolhrak dans le forum C++
    Réponses: 11
    Dernier message: 20/08/2006, 23h37
  5. retour par référence de l'opérateur ++
    Par BigNic dans le forum C++
    Réponses: 4
    Dernier message: 02/08/2006, 18h35

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