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 :

Retourner un long&


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut Retourner un long&
    Bonjour,

    J'ai recuperer une classe dont voici un apercu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class CTest
    {
    public:
        long m_Nb;
        inline long& getNb(void) {return m_Nb;}
    }
    Je ne comprend pas a quoi ca sert de retourner le long&.
    Si qu'elqu'un sait...

    Merci

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    PS: ca marche nickel, a la compilation et a l'execution, c'est juste que je vois pas l'interet.

  3. #3
    Membre chevronné Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Par défaut
    Tu peux modifier ton attribut m_Nb alors que si tu renvoyais long tout court, tu ne pourrais pas... C'est pas forcément mieux, le comportement est différent...

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    Ben comment?

    J'essaye ca mais ca change pas la valeur de ma variable:
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
     
    class test
    {
    public:
    	long n;
    	test() {
    		n = 3;
    	}
     
    	inline long& getTest(void) {return n;}
     
    	void putTest(long m) {
    		n = m;
    	}
    };
     
    int main(int argc, char* argv[])
    {
    	test* essai = new test();
    	long a;
     
    	printf("Test = %d\n", essai->getTest());
    	essai->putTest(5);
    	printf("Test = %d\n", essai->getTest());
    	a = essai->getTest();
    	printf("Test = %d\n", a);
    	a = 2;
    	printf("Test = %d\n", essai->getTest());
     
    	return 0;
    }

  5. #5
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    a est un long, pas une référence, si tu veux modifier n, il faut le faire avant de transformer la référence en long !
    Ensuite, si tu a un getTest comme ça, tu devrais aussi avoir le même qui ne retourne pas de référence en version constante.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    wow puissant!!!
    Donc je suppose que l'interet c'est de faire d'une pierre 2 coups: un put/get en quelque sorte!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    long getNb()
    putNb(long)
     
    devient
     
    long& Nb()
    Ok, merci a vous

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    C'est juste une manière masquée et plus verbeuse de rendre publique une donnée membre. D'autant plus que dans ton cas elle l'était déjà, c'est donc complétement inutile.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    lol c'etait justement ce que j'etais en train de me dire.
    en fait ca sert pas a grand chose, meme si la variable etait priver, si c'est pour faire ca, autant la rendre public, ca evitera de taper des parenthese en plus

  9. #9
    Invité
    Invité(e)
    Par défaut
    et c'est mem plutot dangereux, car généralement, un getter est une fonction const :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long getVal(void) const { ... }
    ce qui veut dire qu'elle n'a pas le droit de modifier l'intégrité de l'objet sur lequel elle travaille

  10. #10
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Ah non, ça sert tout de même à plus que cela. On peut protéger l'accès tout de même, c'est pas mal.
    Le jour où il faut effectuer une action à chaque accès, ça sera facile de le gérer avec une variable privée et ce type d'accesseur.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    Alors dans ce cas question:
    Pour les fonctions inline, le code est bien remplacer, n'est-ce-pas?

    Donc pour le compilo:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    inline long& Nb() {return m_Nb;}
    Pour cette fonction, le code :
    deviendrait:
    Non? (j'avoue que je sais pas trop comment ca marche mais si j'ai bien compris, c'est comme ca).
    Je suppose qu'il faudrait voir en assembleur ce qui sort(comment on fait avec VisualC++2005).

    Dans ce cas quel interet de ne pas mettre la variable directement en public?

  12. #12
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    cf mon message précédent.

  13. #13
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par kacedda
    Dans ce cas quel interet de ne pas mettre la variable directement en public?
    parce qu'on ne met jamais des données membre en public d'une facon générale

  14. #14
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Citation Envoyé par toxcct
    parce qu'on ne met jamais des données membre en public d'une facon générale
    Bouh... le mauvais conseil
    C'est comme ça qu'on se retrouve à écrire ce genre de code pas beau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Vector3D v;
    v.SetX(v.GetX() + v.GetZ());
     
    // Moi je préfère écrire ça :
    v.x += v.z;
    De manière plus générale, lorsqu'on a à manipuler des données sans aucune encapsulation, l'accès publique est beaucoup plus pratique.

  15. #15
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par toxcct
    parce qu'on ne met jamais des données membre en public d'une facon générale

  16. #16
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par Laurent Gomila
    Bouh... le mauvais conseil
    C'est comme ça qu'on se retrouve à écrire ce genre de code pas beau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Vector3D v;
    v.SetX(v.GetX() + v.GetZ());
     
    // Moi je préfère écrire ça :
    v.x += v.z;
    De manière plus générale, lorsqu'on a à manipuler des données sans aucune encapsulation, l'accès publique est beaucoup plus pratique.
    Perso, je préfère :

  17. #17
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    A moi!
    Je préfère soit vraiment encapsuler (classe orientée rôles/services),
    (ce qui dans un cas pareil est vite ridicule)
    soit vraiment ne pas faire semblant d'encapsuler (=> comme laurent) (classe orientée données)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  18. #18
    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
    Perso, j'aimerai bien qu'il y ait des propriétés en C++, histoire de pouvoir écrire v.x += v.z; et que ça fasse v.setX(v.getX()+v.gtZ()). Ne serait-ce que parce que j'ai déjà eu dans des cas de ce type à devoir modifier les accès, par exemple pour logger le nombre d'accès, ou ce genre d'instrumentation. Ou encore pour les classes mathématiques pour pouvoir faire : a.x = 12; cout << a.theta; et autres choses de ce genre.

    Malheureusement, ça n'existe pas, et il y a des gens qui y sont assez opposés au comité (je ne sais pas vraiment pourquoi. La principale raison, je crois, c'est que de code qui a l'air de ne pas faire grand'chose peut faire alors beaucoup de choses). Du coup, on se retrouve à devoir choisir entre écrire du code moche, ou écrire du code non évolutif.
    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.

  19. #19
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    J'avais une idée que je trouvais pas mal pour surcharger l'opérateur . (que ce soit pour les fonctions ou les variables membres) et qui permettait de faire ce genre de chose, entre autres.
    J'en ai parlé sur comp.std.c++ mais j'ai même pas eu une réponse...

  20. #20
    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,
    Citation Envoyé par kacedda
    lol c'etait justement ce que j'etais en train de me dire.
    en fait ca sert pas a grand chose, meme si la variable etait priver, si c'est pour faire ca, autant la rendre public, ca evitera de taper des parenthese en plus
    Si cette manière de voir reste correcte quand tu n'as qu'un seul membre d'un type donné (ici un long) et que tu es sur que ta classe n'en aura jamais qu'un seul, elle devient vite tendancieuse si ta classe doit contenir plusieurs membres d'un meme type, ou qu'elle risque d'évoluer dans ce sens...

    Je vais prendre l'exemple tout simple d'une classe "coordonées" (avec un membre x et un membre y s'il s'agit de coordonnées deux dimentions, ou un membre x, un y et un z pour les coordonnées spaciales), mais ce pourrait etre une classe "couleur" (RGB) ou bien d'autres

    Ces deux (ou trois) valeurs de meme type peuvent tres bien etre mémorisées au sein de la classe de trois manière différentes:
    sous forme séparée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class maclass
    {
        public:
            (...)
        private:
            long x;
            long y;
            long z;
    };
    sous la forme d'un tableau "C style"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class maclass
    {
        public:
            (...)
        private:
            long coord[3];
    };
    sous la forme d'un std::vector (finalement, fort proche du tableau "C style" )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class maclass
    {
        public:
            (...)
        private:
            std::vector<long> coord[3];//ou n'importe quel autre conteneur, 
                                       //d'ailleurs (std::list<long> par exemple ;) )
    };
    Et tu peux, à tout moment (ou presque) décider de modifier ta classe dans l'une ou l'autre de ces optiques.

    Le tout, sans oublier que tu peux tres bien décider à n'importe quel moment que les noms x, y, z ou coord manquent un peu de précision, et donc de leur donner un nom plus explicite

    Et le problème est toujours le meme, y compris avec les classes "orientées données":

    Si tu modifie, pour une raison ou une autre, l'implémentation des membres de ta classe et qu'ils étaient en visibilité publique (donc, sans accesseurs/mutateurs), tout le code qui en dépend (aussi bien le code metier que le code écrit par un utilisateur de la classe que tu aurais fournie sous la forme d'une bibliothèque) devra etre parcourru afin de chercher les endroits où tu accede aux membres afin de le faire correspondre à la nouvelle implémentation (exception faite du passage long coord[3]<==>std::vector<long> coord)...

    Et cela peu etre réparti sur un nombre quasi illimité de fichiers

    Alors que, si tu fournis la classe avec une encapsulation forte (membres privés avec accesseurs et mutateurs ), finalement, si tu décide de modifier l'implémentation, tout ce que tu as à faire, c'est à modifier les mutateurs et accesseurs, vraissemblablement dans un seul fichier, et le tour est joué

    Et, dans un tel cas, la seule raison de s'éviter à avoir écrire les parenthèses devient... pour le moins légère par rapport au travail d'adaptation à fournir en cas de changements

    Sauf, bien sur, s'il est clair, sur et certain, que la classe n'évolura plus par la suite (soit par conception, soit par décision arbitraire)...

    Comme tu précise que "c'est une classe que tu as récupérée", il semble cohérent que le créateur ait décidé de mettre un accesseur...

    Par contre, c'est incohérent par le simple fait d'avoir laissé le membre en visibilité publique, vu que l'accesseur et le membre sont tous les deux visibles de partout (une visibilité privée ou, au minimum protégée aurait vraissemblablement été préférable)

    A titre personnel, et bien que ce soit plus lourd à l'utilisation, je présume - n'ayant jamais été réellement confronté au problème - que j'aurais tendance à utiliser plutot l'accesseur que le membre lui-même, en espérant (car, si le concepteur a su faire cette erreur, on peut craindre que l'espoir soit vain) que le concepteur aie le bon gout de laisser l'accesseur s'il vient à modifier l'implémentation de la classe
    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. Arrêter un prog si temps de connexion trop long
    Par jakouz dans le forum Langage
    Réponses: 4
    Dernier message: 22/10/2002, 18h28
  2. convertir un nom long (win32) en format dos (8+3)
    Par kylekiller dans le forum Langage
    Réponses: 2
    Dernier message: 30/08/2002, 13h34
  3. String -> long double (_strlold ?)
    Par haypo dans le forum C
    Réponses: 7
    Dernier message: 25/07/2002, 20h22
  4. [Manip de fichiers] Fonction retournant des infos
    Par sans_atouts dans le forum C
    Réponses: 3
    Dernier message: 24/07/2002, 14h16
  5. Réponses: 2
    Dernier message: 05/06/2002, 12h29

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