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 :

Récuperation de valeur


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 50
    Points : 59
    Points
    59
    Par défaut Récuperation de valeur
    Bonjour...

    Je souhaite faire ceci (en théorie ):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int w = _max.Get_Position.Get_X() - _min.Get_Position.Get_X();
    sachant que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Truc _max(10,0);
    Truc _min(0,0)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Truc
    {
    private:
    Point _mPt;
    ...
     
    public:
    Truc(int x, int y) {_mPt = Point(x,y);}
    ~Truc() {}
    const Point& Get_Position() const {return _mPt;}
    }
    et que la classe Point est définie de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Point
    private:
    int _X;
    int _Y;
    public:
    Point(int x, int y) {_X = x; _Y=y;}
    ~Point() {}
    const int& Get_X() const {return _X;}
    const int& Get_Y() const {return _Y;}
    }
    Lorsque je compile mon code sous visual studio, celui me sort l'erreur :
    error C2228: la partie gauche de '.Get_X' doit avoir un class/struct/union
    Pourriez-vous eclairer ma lanterne face à ce petit problème fort simple, mais pour moi d'une complexité redoutable...

    Bon, je continue à googler....

    Merci

    PS: je viens de C#...

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Salut,

    Get_Position c'est une fonction. Pour appeler une fonction faut mettre des parenthèses. _max.Get_Position().Get_X()
    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 du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 50
    Points : 59
    Points
    59
    Par défaut
    Salut...

    ça, je le sais...

    Lorsque je l'ai écrit et compilé, VS m'a sorti ce genre de réflexion :
    l'objet a des qualificateurs de types incompatibles avec la fonction membre ...
    d'où le retrait des parenthèses sur Get_Position pour essayer.

    Bon, suite à ta réflexion, j'ai remis les parenthèses et Ô Miracle, je compile sans problème...

    Maintenant, comment puis-je modifier la valeur de _X appartenant à _mPt à partir de _max ? Sans passer par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // Fonction de la classe Truc
    void Change_X(const int& x)
    {
    _mPt.X = x;
    }
    Voyez-vous la chose ?

  4. #4
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Je comprends mal ou tu demandes comment changer une variable private depuis l'extérieur de la classe sans passer par une fonction ?
    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.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 50
    Points : 59
    Points
    59
    Par défaut
    Dans ma tête, c'est clair

    Je suis habitué sous c# à utiliser les propertys Get et Set... donc j'aimerai reprendre le même principe...
    Je connais la chose suivante sous c++ (après recherche) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    __declspec(property(put = Set_X, get = Get_X)) int X
    Alors, tu dis :
    tu demandes comment changer une variable private depuis l'extérieur de la classe sans passer par une fonction ?
    Pour ça, j'ai ma fonction Set_X(const int& x) qui est public et je voudrai toujours l'utiliser.

    Donc pour faire simple :
    mMin (contient _mPt [modifiable par Set_Point] (contient _X [modifiable par Set_X]))
    Suis-je obligé de créer la fonction suivante ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Fonction de la classe Truc
    void Change_X(const int& x)
    {
    _mPt.X = x;
    }
    Mais dans ce cas, si ma classe Point contient plusieurs variables, dois-je écrire une fonction pour chaque variable que je souhaite modifier ultérieurement comme Change_X ?
    N'y a t-il pas un moyen un peu plus direct ?

    J'espère que mon explication est un peu plus clair...

    Merci pour la patience...

  6. #6
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Bonjour

    Citation Envoyé par Dokare Voir le message
    N'y a t-il pas un moyen un peu plus direct ?
    Si, mettre les données membres en public (ou avoir une fonction membre qui renvoi une référence). Cela a du sens pour la classe point.
    De façon générale, on ne peut mettre une donnée membre en public uniquement si l'utilisateur peut l'utiliser sans mettre l'objet dans un état incohérent.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 50
    Points : 59
    Points
    59
    Par défaut
    Bonjour...

    Si, mettre les données membres en public (ou avoir une fonction membre qui renvoi une référence). Cela a du sens pour la classe point.
    Cela revient à changer ma class Point en struct Point. Mais je veux un contrôle des valeurs insérer dans Point (genre min et max), d'où la nécessité d'une fonction membre...

    Bon toujours est-il que je pense avoir trouvé ma solution après étude de vos remarques...
    Je vous écrit mon code et dites ce que vous en pensez !!! Merci d'avance...

    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
    33
    34
    35
    36
    37
    38
     
    class Point
    {
    private:
    	int _X;
    	int _Y;
    public:
    	Point() { _X = 0; _Y = 0; }
    	Point(const int& x,const int& y) : _X(x), _Y(y) {}
    	~Point() {}
     
    	int Get_X() { return _X; }
    	int Get_Y() { return _Y; }
     
    	void Set_X(const int& x) { _X = x; }
    	void Set_Y(const int& y) { _Y = y; }
    };
     
    Class Truc
    {
    private:
    	Point _Pt;
    public;
    	Truc() { _Pt = Point(0, 0); }
    	~Truc() {}
     
    	Point Get_Point() { return _Pt; } // Ne doit pas être const car je veux modifier ultérieurement les valeurs de _Pt
    	void Set_Point(const Point& pt){ _Pt = pt; }
    }
     
    int Main(...)
    {
    	Truc t;
     
    	t.Get_Point().Set_X(10); // _X de _Pt doit valoir 10
     
    	int y = t.Get_Point().Get_Y(); // y doit être égale à 0
    }
    Merci pour vos conseils...

    Cdt

  8. #8
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Citation Envoyé par Dokare Voir le message
    Cela revient à changer ma class Point en struct Point. Mais je veux un contrôle des valeurs insérer dans Point (genre min et max), d'où la nécessité d'une fonction membre...
    Par conception, je dirais que la classe point doit être template avec x et y public.

    C'est ton type qui doit appliquer les limitations de façon transparente.

    Voici un exemple pour illustrer (int_10_100_t devrait être template pour plus de généricité et il faut fournir les opérateur arithmétique et les traits de la std qui vont bien) :
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    // g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++11 -pedantic -fopenmp main.cpp -o main && ./main
    // g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++98 -pedantic -fopenmp main.cpp -o main && ./main
     
    #include <iostream>
    #include <algorithm>
     
     
    template <class T>
    class point
    {
    public:
     
    	T x;
     
    	T y;
     
    	point() : x(), y() { }
     
    	point(T const & x, T const & y) : x(x), y(y) { }
    };
     
    template <class T>
    std::ostream & operator <<(std::ostream & o, point<T> const & point)
    {
    	o << "{ " << point.x << ", " << point.y << " }";
    	return o;
    }
     
     
    class int_10_100_t
    {
    private:
     
    	int m_i;
     
    public:
     
    	int_10_100_t(int const i = 0) : m_i(std::max(std::min(i, 100), 10)) { }
     
    	int i() const { return m_i; }
    };
     
    std::ostream & operator <<(std::ostream & o, int_10_100_t const i)
    {
    	o << i.i();
    	return o;
    }
     
     
    int main()
    {
    	point<int_10_100_t> p;
    	std::cout << p << std::endl; // { 10, 10 }
     
    	p.y = 500;
    	std::cout << p << std::endl; // { 10, 100 }
     
    	return 0;
    }

  9. #9
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Point Get_Point() { return _Pt; } // Ne doit pas être const car je veux modifier ultérieurement les valeurs de _Pt
    Que signifie ton commentaire ? Quel rapport entre const et modifier _Pt ?
    Vu que tu retournes ton Point par copie, ça n'a aucun sens.

    Cela revient à changer ma class Point en struct Point.
    http://cpp.developpez.com/faq/cpp/?p...lass-et-struct

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    __declspec(property(put = Set_X, get = Get_X)) int X
    Et te voilà bloqué à Visual Studio parce qu'il s'agit d'une extension du compilateur.
    En plus cette technique n'apporte strictement rien, puisque Set_X et Get_X doivent exister, et je pense que n'importe quel programmeur assez sensé pour écrire myTruc.X = 10; sera aussi capable d'écrire myTruc.Set_X(10);, non ?
    Si tu veux faire du C++, fais du C++, et n'essaye surtout pas de copier le C#, sinon reste à faire du C#.
    Vouloir copier les mécanismes, à fortiori sans comprendre ce qui se cache derrière, c'est juste le meilleur moyen de faire n'importe quoi et du mauvais code.

    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
    class Point
    {
    private:
    	int _X;
    	int _Y;
    public:
    	Point() { _X = 0; _Y = 0; }
    	Point(const int& x,const int& y) : _X(x), _Y(y) {}
    	~Point() {}
     
    	int Get_X() { return _X; }
    	int Get_Y() { return _Y; }
     
    	void Set_X(const int& x) { _X = x; }
    	void Set_Y(const int& y) { _Y = y; }
    };
    Quand une classe propose getter et setter triviales sur un attribut, ça revient à avoir un attribut public.

    Mais dans ce cas, si ma classe Point contient plusieurs variables, dois-je écrire une fonction pour chaque variable que je souhaite modifier ultérieurement comme Change_X ?
    N'y a t-il pas un moyen un peu plus direct ?
    Si, le meilleur moyen c'est d'avoir une architecture et du code clair.
    Soit tu manipules un Truc, soit tu manipules un Point.
    Vouloir manipuler un Point à travers Truc c'est juste bancal.
    Si Truc camoufle le Point, l'utilisateur n'en a rien à faire que ce soit un Point, int ou Tartempion derrière. Lui il veut manipuler un Truc. Avec l'interface de Truc.
    S'il a besoin de manipuler le Point de Truc, il lui faut un vrai accès au Point.
    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.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 50
    Points : 59
    Points
    59
    Par défaut
    'Soir Bousk et Ehonn...

    J'ai l'impression de me faire gronder ???? !!! Nan, ou alors j'interprête mal tes propos...

    Concernant ton dernier poste Ehonn, pour parler par métaphore :
    J'apprend à cuire un steack haché, tu me donnes la recette du boeuf bourguignon
    Et il me manque certaines notions comme me le rappelle Bousk...

    En tout cas, vos remarques m'ouvre de nouvelles voies de reflexion et une meilleur approche de c++...

    Merci beaucoup et bonne soirée

    Fini l'introduction... Passons à l'étude de mon bazard.

    PS : je viens de C#
    J'utilise ces classes pour faire des essais et comprendre certains mécanismes, d'où mes questions car je n'ai pas le vocabulaire adéquat du programmeur pour expliquer ce que je souhaite faire...

    Bousk :
    Que signifie ton commentaire ? Quel rapport entre const et modifier _Pt ?
    Si je met const, je ne peux modifier le contenu de _Pt._X (par exemple) d'accord ? ... Hors, je ne veux pas rendre celle-ci public car plus tard, je pense créer des tests sur la future valeur modifiée (pourquoi, ben parce que...), donc contrôler une future valeur...

    Après entre struct et class, ben euhhh, je n'ai pas encore eu la révélation... 2ème

    Et te voilà bloqué à Visual Studio parce qu'il s'agit d'une extension du compilateur.
    Ben ouais et alors ... Donc ce n'est pas une petite spécifité de c++ , content de l'apprendre... De toute façon, je suis retourné à mes accesseurs simples (Get_ et Set_).
    Pour info, je suis censé mais curieux et les reflèxes (c#) ont la vie dur ... Donc je dois faire avec et trouvé le moyen de ne pas me perdre dans ces 2 langages.
    J'ai pas fini de m'arracher les cheveux...

    De plus, je souhaite avoir un code clair (plus facile à relire), car un problème compliqué est uniquement composée d'une série de problèmes simples (normalement). Mes fonctions sont censés s'améliorer en complexité et ne pas se contenter d'un vulgaire retour de valeur (l'exemple que j'ai écrit bien entendu)...

    Voila pourquoi je pose ce genre de questions, car les tutos et livres sont réputés pour être constant et non direct...

    Toujours est-il que je ne sais pas si mon code est de premier abord correct ? Tant au niveau de l'esthétisme que pratique...

    Bon j'y vais, il a le film sur TF???

    A+

  11. #11
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Arf, désolé, c'est pas du tout mon intention

    C'est pas toujours évident de se faire comprendre en mode texte en écrivant des messages relativement court.

    Bref, mon idée est de penser à la généricité du code. Si tu sais utiliser std::vector, tu sais comment utiliser une classe template pour avoir un tableau d'entier tu utilises le type std::vector<int>, pour un tableau de chaînes de caractères std::vector<std::string> et pour un tableau d'entier positif std::vector<unsigned int>. L'idée est d'avoir une classe qui gère un tableau de T (peut importe T) et d'écrire qu'une fois cette classe (ici std::vector).

    La classe point ressemble à std::vector dans le sens où tu peux avoir envie d'utiliser des coordonnées entières point<int> ou flottantes point<double> ou compris entre 10 et 100 (comme dans mon exemple point<int_10_100_t>).
    De ce fait la classe point est template et x et y sont public.

    Premier cas : tu as envie que x et y soit compris entre 10 et 100. Ils faut que le type de x et y ne soit pas int mais un type qui force l'entier à être entre 10 et 100. Pas le choix il faut créer ton type, et pour cela j'ai proposé int_10_100_t. Une fois combiné à point<T>, x et y sont des int_10_100_t et x et y seront bien compris entre 10 et 100.

    Deuxième cas : tu as envie que x et y s'influencent (par exemple 2 * x > y. Pas le choix ici, le plus simple et de recoder point (et l'appeler probablement différemment) pour ajouter une telle contrainte. Et ici faire les données membres seront probablement private pour que l'utilisateur ne puissent pas mettre l'objet dans un état incohérent.

    Troisième cas : les limitations de x et y sont différentes mais ne sont pas liées, dans ce cas x et y ne sont tout simplement du même type, par exemple pour std::pair<int, double> la première donnée membre .first sera un entier et la seconde .second sera un flottant.

    --- --- ---

    J'ai envie de te dire « Bienvenue dans le monde de la conception générique de C++ ». Ces concepts ne s'apprennent pas en un jour il faut écrire du code et tester pour commencer à comprendre pourquoi la généricité de C++ est si puissante. Commence peut-être par jouer avec std::vector et std::pair et relis / teste attentivement le code que j'ai poster.
    N'hésite pas à poser des questions (après un peu recherche en amont ) si tu en as. On est ici pour t'aider et on le fait avec plaisir (même si la rapidité ou le contenu des messages peut surprendre)

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 50
    Points : 59
    Points
    59
    Par défaut
    Merci encore Ehonn pour ces informations...

    Je vais étudier tout ça...

    Bon, je peux dire que j'ai résolu mon problème...

    Bonne journée et à la prochaine sur le forum

  13. #13
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    Bonjour,


    Un petit point pour compléter les explications :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Point(const int& x,const int& y) : _X(x), _Y(y) {}
    Pourquoi utiliser des références constantes dans ce cas. Pour des int, autant utiliser un passage par valeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Point(int x, int y) : _X(x), _Y(y) {}
    Il est préférable de réserver le passage par référence constante pour les objets complexes, et d'utiliser un passage par valeur pour les types de base.

  14. #14
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Dokare Voir le message
    Si je met const, je ne peux modifier le contenu de _Pt._X (par exemple) d'accord ? ... Hors, je ne veux pas rendre celle-ci public car plus tard, je pense créer des tests sur la future valeur modifiée (pourquoi, ben parce que...), donc contrôler une future valeur...
    Tu es encore à côté de la plaque. Tu devrais vraiment commencer par prendre un cours de syntaxe de base..
    C'est ta méthode qui est const. Une méthode const c'est... que le this n'est pas modifié quand on l'appelle.
    Vu que tu retournes ton Point par copie, ce que tu retournes n'a strictement rien à voir avec le Point de ta classe.

    http://cpp.developpez.com/faq/cpp/?p...apres-leur-nom
    Décidément, notre FAQ est plutôt bien fournie. Faut un peu être curieux et cliquer dessus par contre.
    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.

  15. #15
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    En outre, et c'est surtout là que va se poser le problème, l'utilisation des accesseurs (get_) et des mutateurs (set_) est le symptome évident que tu penses à tes classes en termes de données :

    Il semble en effet évident que ta classe Point n'est que l'agrégation de deux données (x et y), alors que tu devrais réfléchir en termes de services proposés par cette classe.

    En effet, si tu peux considérer ta classe point comme n'étant qu'un agrégat de données, mais il n'y a alors absolument aucun intérêt à placer les données qu'elle contient dans l'accessibilité privée, si c'est pour fournir un accesseur et (surtout) un mutateur sur charcune de ces données : places les dans l'accessibilité publique, et tu sera tranquille : tu pourra y accéder et meme les modifier depuis strictement n'importe où .

    Et c'est là que tu vas sans doute me faire la réflexion que "oui, mais alors, je perds l'encapsulation" En effet... tu n'as pas vraiment tort ... Mais, dis moi, si tu fourni le mutateur sur les données membre (set_x, set_y), tu n'as pas l'impression que cela revient au même : tu laisses le soin à l'utilisateur de ta classe de s'assurer que la nouvelle abscisse ou la nouvelle ordonnée est comprise dans l'intervalle de valeur admissibles (autrement dit : que ton point pourra être considéré comme valide dans le référentiel dans lequel tu veux le placer). C'est pas beaucoup mieux

    L'idée de l'encapsulation, c'est de se dire que "l'utilisateur de la classe n'a pas à savoir comment les données sont gérées" parce qu'il va se contenter d'utiliser des services rendus par la classe en question.

    Typiquement, on n'est en droit de n'attendre que deux services bien précis de la part d'une classe Point utilisée dans un référentiel 2D : obtenir sa position sur l'axe des x et obtenir sa position sur l'axe des y, ET C'EST TOUT!!!!
    Pourquoi? Simplement parce que -- c'est courant avec les classes ayant sémantique de valeur -- si tu modifies l'une de ces positions, tu obtiens tout simplement un autre point.

    Les accesseurs (get_x, get_y) correspondent donc à des services que l'on est sans doute en droit d'attendre de la part d'un point, mais les mutateurs ne servent à rien : si tu veux un point qui se trouve à une distance horizontale X et à une distance verticale Y d'un autre, rien ne t'empêche d'avoir un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Point p1(10, 20);
    Point p2(p1.getX()+15,p1.getY()+10);
    mais il n'y a aucune raison apparente à modifier ton point d'origine

    L'avantage, c'est que si tu as mis un invariant sur les valeurs admises pour x et pour y, tu pourras les vérifier directement dans le constructeur et (ré)agir en conséquence si ces invariants ne sont pas respectés

    Par contre, si tu voulais forcer cette vérification au niveau d'un mutateur, tu mentirais à l'utilisateur sur ce que la fonction setX (ou setY) fait réellement, car la modification serait soumise à la vérification de cet invariant. Le nom des fonctions devrait donc être proche de checkAndSetX (checkAndSetY) et ces fonctions devraient soit utiliser une assertion, soit lancer une exception ou renvoyer une valeur de réussite (peut être même faire deux de ces choses ).

    Le tout sans compter sur la notion "d'instantanéité" d'une fonction nommée set : à un instant T (avant l'appel à la fonction), la donnée est d'une valeur particulière et à l'instant T+1 (après l'appel de cette fonction), la même donnée a une valeur différente, équivalente à celle qui a été transmise.

    C'est rarement le genre de comportement qui nous intéresse (ex : setPosition(Point const&), serait bien mieux nommé sous la forme de moveTo(Point const &) ou de move(int diffX, int diffY) car la sémantique que l'on applique à move laisse la possibilité de faire en sorte que ce ne soit pas "instantané" (voire, que le trajet ne puisse pas aboutir ) )
    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. récuperer la valeur d'un paramètre
    Par pelelive dans le forum Access
    Réponses: 4
    Dernier message: 13/06/2005, 16h10
  2. [VB.NET]Récuperer des valeurs d'une autre page
    Par Dnx dans le forum ASP.NET
    Réponses: 8
    Dernier message: 12/05/2005, 16h19
  3. [JCheckBox] Récuperer les valeurs
    Par Regis.C dans le forum Composants
    Réponses: 3
    Dernier message: 12/04/2005, 21h19
  4. Récuperer la valeur d'un entier
    Par Sniper37 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/03/2005, 12h13
  5. [jsp] récuperation de valeur d'un formulaire
    Par peppena dans le forum Servlets/JSP
    Réponses: 12
    Dernier message: 30/03/2004, 21h00

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