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 :

[notation] Noms des parametres du constructeur


Sujet :

C++

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Citation Envoyé par screetch Voir le message
    pourquoi pas avoir les parametres x et y et utiliser this->x et this->y pour les membres ? il me semble que la semantique de this->x et this->y est tout a fait claire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct Point
    {
       int x;
       int y;
       Point(int x = 0, int y = 0) : x(x), y(y) { }
       void set(int x = 0, int y = 0) { this->x = x; this->y = y; }
    }
    On pourrait y voir deux raisons principales:
    1. Dans le cas de méthodes plus complexes, il peut assez rapidement être très lourd d'avoir toujours à se "palucher" l'indirection this->.

      Tant que l'on en reste avec la structure Point, cela ira, mais, il faut penser qu'il y aura toutes les autres structures qui tournent autour, pour lesquelles il s'agira de garder un minimum de cohérence dans les conventions, et pour lesquelles il n'est pas impossible d'avoir des méthodes plus complexes
    2. Bien que "this->" est implicite quand il n'y a pas d'ambiguité, il faudrait voir si, le fait de devoir la rajouter explicitement n'est pas de nature à amener une baisse de performance du fait du déréférencement que cela implique

    Pour le (2), je ne sais à vrai dire pas quel est le cout en terme de perfs de l'indirection explicite... Mais, dans le doute...
    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

  2. #22
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Dans le cas de méthodes plus complexes, il peut assez rapidement être très lourd d'avoir toujours à se "palucher" l'indirection this->.
    J'ai envie de dire que si tu as des objets plus complexes avec des méthodes plus complexes, alors il faut encapsuler et passer par des accesseurs. Pour moi, la question initiale se pose pour des types simples et couramment utilisés (Point.x, Point.y, Size.cx, Rect.top, Couleur.r, Fenetre.hwnd ....).
    Citation Envoyé par koala01 Voir le message
    Bien que "this->" est implicite quand il n'y a pas d'ambiguité, il faudrait voir si, le fait de devoir la rajouter explicitement n'est pas de nature à amener une baisse de performance du fait du déréférencement que cela implique
    Le code généré dans VC et gcc est le même dans les deux cas. Il y a un déréférencement avec le paramètre implicite this dans les deux cas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	void MaMethode(MaClasse *P_pObjet){
    		m_x = 4;
    		this->m_x = 5;
    		P_pObjet->m_x = 7;
    	}
    on a:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    		m_x = 4;
    mov  0x8(%ebp),%eax -> Déréfencement du premier paramètre: this 
    movl $0x4,(%eax)
    		this->m_x = 5;
    mov  0x8(%ebp),%eax -> Déréfencement du premier paramètre: this 
    movl $0x5,(%eax)
    		P_pObjet->m_x = 7;
    mov  0xc(%ebp),%eax -> Déréfencement du second paramètre: P_pObjet 
    movl $0x7,(%eax)

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    J'ai envie de dire que si tu as des objets plus complexes avec des méthodes plus complexes, alors il faut encapsuler et passer par des accesseurs. Pour moi, la question initiale se pose pour des types simples et couramment utilisés (Point.x, Point.y, Size.cx, Rect.top, Couleur.r, Fenetre.hwnd ....).
    Ne connaissant à la base qu'une classe minimale, et n'ayant qu'une seule information sur les souhaits du client il devient difficile de partir sur des "approximations" personnelles...

    Je reconnais avoir pris le "cas extrême", mais je trouve que tu fais à l'opposé preuve d'un peu trop d'optimisme quant aux souhaits du client...

    Il est fort vraisemblable (du moins, je l'espère pour notre pauvre r0d ) que le client souhaite quelque chose se trouvant quelque part à mi chemin entre les deux points de vue
    Le code généré dans VC et gcc est le même dans les deux cas. Il y a un déréférencement avec le paramètre implicite this dans les deux cas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	void MaMethode(MaClasse *P_pObjet){
    		m_x = 4;
    		this->m_x = 5;
    		P_pObjet->m_x = 7;
    	}
    on a:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    		m_x = 4;
    mov  0x8(%ebp),%eax -> Déréfencement du premier paramètre: this 
    movl $0x4,(%eax)
    		this->m_x = 5;
    mov  0x8(%ebp),%eax -> Déréfencement du premier paramètre: this 
    movl $0x5,(%eax)
    		P_pObjet->m_x = 7;
    mov  0xc(%ebp),%eax -> Déréfencement du second paramètre: P_pObjet 
    movl $0x7,(%eax)
    J'avais précisé mon doute sur la deuxième raison que je donnais...

    Mais c'est bien gentil quand même de le lever si élégamment
    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

  4. #24
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    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 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    J'ai envie de dire que si tu as des objets plus complexes avec des méthodes plus complexes, alors il faut encapsuler et passer par des accesseurs.
    Dans ce cas là, encapsuler oui.
    Passer par des accesseurs, seulement si cela a du sens. En particulier, ce sont rarement des mutateurs triviaux qui aident à déléguer, ou qui encapsulent quoi que ce soit.
    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...

  5. #25
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    que pense tu d'une sémantique comme cela?
    http://qt.developpez.com/doc/4.4/qpoint/

  6. #26
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Je ne sais pas qui est le "tu" de la question, mais je vais répondre quand même...

    Pour moi, cette classe n'encapsule aucunement le fait qu'elle possède une variable membre x, et une autre y, toutes deux de type entier (je vois mal comment implémenter par exemple la fonction rx autrement). Dans ce cas, autant mettre directement en accès public ces variables.

    C'est plus clair, plus simple, moins hypocrite, et peut-être même plus performant.

    A mon avis, le seul avantage d'écrire cette classe ainsi est d'éviter d'avoir à répondre sans cesse à des questions de gens qui n'ont pas bien compris l'encapsulation et en ont retenu une mauvaise règle qui serait : Tout mettre en privé tout le temps.

    Si je voyais une telle classe dans du code dont j'ai la responsabilité, je la modifierais probablement. Sans compter qu'elle a d'autre problèmes (qu'est-ce que la longueur d'un point ?... Ne serait-il pas préférable d'en faire une classe immuable...). J'aime bien Qt dans son ensemble, ne serait-ce que par manque de concurrence, mais il m'arrive très souvent de ne pas trop aimer ce que j'y vois quand j'entre dans les détails.
    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.

  7. #27
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je ne sais pas qui est le "tu" de la question, mais je vais répondre quand même...
    je sais pô non plus

    C'est plus clair, plus simple, moins hypocrite, et peut-être même plus performant.
    Pourquoi moins hypocrite???

    A mon avis, le seul avantage d'écrire cette classe ainsi est d'éviter d'avoir à répondre sans cesse à des questions de gens qui n'ont pas bien compris l'encapsulation et en ont retenu une mauvaise règle qui serait : Tout mettre en privé tout le temps.
    Pas bien compris ou mal appris... je doit faire partie de ceux là , sauf que j'aime pas private et utilise plutôt protected....
    Pour moi une class avec des fonctions protège ses données par de get/set. Cela permet surtout, de pouvoir ajouter du code si il le faut (c'est surement pas le plus propre).
    Une class contenant que des données n'as pas de get/set.

    J'aime bien Qt dans son ensemble, ne serait-ce que par manque de concurrence, mais il m'arrive très souvent de ne pas trop aimer ce que j'y vois quand j'entre dans les détails.
    Aprés c'est difficile de gérer du code aussi gros sans lacune...

  8. #28
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    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 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Citation Envoyé par Mongaulois
    Pour moi une class avec des fonctions protège ses données par de get/set. Cela permet surtout, de pouvoir ajouter du code si il le faut (c'est surement pas le plus propre).
    Une class contenant que des données n'as pas de get/set.
    Je vais plus loin, j'évite de mettre des setXXX(), et privilégie immuabilité (pour les données qui n'ont pas de raison de changer unitairement), fonctions dédiées qui changent tout de manière cohérente, et mutateurs non triviaux qui vont avoir un nom qui n'est pas en setXXX().

    Chez moi, les get sont régulièrement nécessaires pour des raisons de débuggage via fichiers de log.


    Quant au rx() de la classe montrée. Mon premier réflexe est "Quelle horreur!" Dans le genre je n'encasule rien, mais je fais croire à ceux qui n'ont pas compris l'encapsulation que je l'ai comprise, elle est pas mal.
    /me adepte du "ne jamais donner un accès direct et complet aux détails membres" (i.e. pas d'accès en référence non constante sur les attributs privés)
    Enfin. Je dis ça, mais peut-être qu'en interne qui ont mis en œuvre la classe comme le type extent_t d'un concurrent un jour peut-être. C'est sûr que chez eux le côté : "je peux changer l'implémentation de façon quasi-transparente sans impacter le code client" est un plus vrai que ce peut l'être dans un code qui n'est pas celui d'une bibliothèque vendue à des clients.


    Quant à protégé/privé, quand j'ai le temps de faire propre, j'ai tendance à privilégier la données en privé, quitte à fournir un mutateur non trivial (ou pas de mutateur du tout), et un accesseur, tous deux protégés. Cela me donne un meilleur contrôle des invariants.
    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...

  9. #29
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    et privilégie immuabilité (pour les données qui n'ont pas de raison de changer unitairement)
    Pourrais tu explique ce que tu entend par immuabilité? J'ai du mal à comprendre le principe...

    C'est sûr que chez eux le côté : "je peux changer l'implémentation de façon quasi-transparente sans impacter le code client" est un plus vrai que ce peut l'être dans un code qui n'est pas celui d'une bibliothèque vendue à des clients.
    C'est pour cela que je trouve l'idée intéressante... A chaque fois que j'ai une class qui manipule ses données, je me dit qu'il faut mieux une fonction pour modifier, si besoin, certain comportement du code (optimisation) dans le futur...
    Par exemple, je décide de stocker la norme d'un vecteur, pour ne pas la recalculer à chaque fois. Seulement, à chaque fois que je change x ou y, il faut la recalculer. Si je n'ai pas utiliser de fonction (get/set ou autre) je n'ai aucune possibilité de le savoir.

    Quant à protégé/privé, quand j'ai le temps de faire propre, j'ai tendance à privilégier la données en privé, quitte à fournir un mutateur non trivial (ou pas de mutateur du tout), et un accesseur, tous deux protégés. Cela me donne un meilleur contrôle des invariants.
    et donc des get/set.... non?

    Ce que je comprend, en lisant d'autre thread, le problème est la signification de get/set qui est trop vague et porte à confusion et qu'il faut mieux utiliser un nom plus explicite. Après faut trouver...
    Mettre un membre public au lieu de le protéger, je n'ai pas trouvé de bonne raison ou exemple... Sauf une class contenant que des données.

  10. #30
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Pourrais tu explique ce que tu entend par immuabilité? J'ai du mal à comprendre le principe...
    Ben l'immuabilité, c'est le fait de ne pas modifier ses données. En ne donnant pas de setXXX(), tu interdis cela.

    L'explication, c'est dans la même lignée que les 'const' partout !

    Un objet qui rend des services, elle doit maintenir l'ensemble de ses données internes de manière cohérente.
    -> tu as des préconditions, et post-conditions avant et après chaque service rendu.

    Si on autorise les setXXX() à tout va même sur des données critiques, bonne chance pour trouver les bugs ou pour montrer que ton programme est sûr.

    La plupart des bugs dans les programmes viennent des effets de bords, parce qu'on a pas modifié telle ou telle donnée avant ou après. Parce qu'on a oublié ça.

    Performance oblige, dans un langage principalement impératif comme le C++, tu ne peux pas toujours faire comme chez les langages fonctionnels performants style OCaml, en appliquant des fonctions pures à tes données (sans effets de bord).

    Tu es donc obligé de modifier la donnée sur place, et donc fournir des fonctions qui modifient les données.
    Quitte à rendre un service, autant que la fonction qui rend ce service fasse elle-même tout et bien, sans que moi j'ai à me préoccuper des détails d'implémentation.

    Avec des boîtes noires, c'est bien plus facile de prouver que ta classe ou ton module est correct !
    C'est bien le principe de l'encapsulation nan ? (qui en plus n'est pas propre à l'orienté objet)

    En plus, ta classe est bien plus facile à utiliser de cette manière si tu fais gaffe à faire le juste équilibre (interface plus simple et moins bruitée) !

  11. #31
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Pourquoi moins hypocrite???
    Parce que c'est faire semblant de dire qu'on peut changer l'implémentation, alors qu'en pratique, on ne peut pas (sauf une délégation à une sous-classe comme indiqué dans l'exemple de Luc/Adobe). Voir plus bas.

    Citation Envoyé par Mongaulois Voir le message
    Pourrais tu explique ce que tu entend par immuabilité? J'ai du mal à comprendre le principe...
    Regarde par exemple les classes string de Java ou C#. Tu peux construire une nouvelle string à partir d'une opération sur une string existante, mais tu ne peux pas modifier une string. Ca peut conduire à du code plus clair, et entre autre, c'est mieux si tu souhaites paralléliser le code.


    Citation Envoyé par Mongaulois Voir le message
    Par exemple, je décide de stocker la norme d'un vecteur, pour ne pas la recalculer à chaque fois. Seulement, à chaque fois que je change x ou y, il faut la recalculer. Si je n'ai pas utiliser de fonction (get/set ou autre) je n'ai aucune possibilité de le savoir.
    Sauf que dans l'exemple Qt::qpoint, ça n'est plus possible. Tu ne sais pas quand l'utilisateur décide de modifier la donnée par la référence que tu lui as inconsidérément fournie.
    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.

  12. #32
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Sauf que dans l'exemple Qt::qpoint, ça n'est plus possible. Tu ne sais pas quand l'utilisateur décide de modifier la donnée par la référence que tu lui as inconsidérément fournie.
    si tu à un accés const et non const si. Exemple avec x() et y() pour const et rx() et ry() pour les non const (ce que fait Qt::qpoint d'ailleur). Bon j'ai abusé avec les ref const de double, mais c'est pour l'exemple

    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
    #include <iostream>
    #include <cmath>
    class CPoint
    {
    	double m_x;
    	double m_y;
    	bool m_calculerNorme;
    	double m_norme;
    public :
    	CPoint(double x,double y) 
    		:m_x(x),m_y(y),m_calculerNorme(true),m_norme(0.)
    	{
    	};
    	double & rx()  
    	{
    		m_calculerNorme = true;
    		return m_x;
    	}
    	const double & x() const 
    	{
    		return m_x;
    	}
     
    	double & ry()  
    	{
    		m_calculerNorme = true;
    		return m_y;
    	}
     
    	const double &y() const
    	{
    		return m_y;
    	}
     
    	const double & norme()
    	{
    		if (m_calculerNorme)
    		{
    			std::cout<<"oui : ";
    			m_norme = sqrt(x()*x()+y()*y());
    			m_calculerNorme = false;
    		}
    		return m_norme;
    	}
    };
     
    int main(int argc, char* argv[])
    {
    	CPoint p(10.,12.);
    	std::cout<<"norme : "<<p.norme()<<std::endl;
    	const CPoint & const_p =p;
    	double x_y = abs(p.x())+abs(p.y());
    	std::cout<<"norme : "<<p.norme()<<std::endl;
    	p.rx()+= 10;
    	std::cout<<"norme : "<<p.norme()<<std::endl;
     
    	return 0;
    }
    ps :tien un effet de bord assez drôle
    std::cout<<"norme : "<<p.norme()<<std::endl;
    peut ecrire
    oui : norme : ...
    au lieu de
    norme : oui : ...

  13. #33
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Comment ton code gère-t-il :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
    	CPoint p(10.,12.);
    	std::cout<<"norme : "<<p.norme()<<std::endl;
    	double &d = p.rx();
    	std::cout<<"norme : "<<p.norme()<<std::endl;
            sleepPendant2h();
            d*=2;
    	std::cout<<"norme : "<<p.norme()<<std::endl;
    }
    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.

  14. #34
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Comment ton code gère-t-il :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
    	CPoint p(10.,12.);
    	std::cout<<"norme : "<<p.norme()<<std::endl;
    	double &d = p.rx();
    	std::cout<<"norme : "<<p.norme()<<std::endl;
            sleepPendant2h();
            d*=2;
    	std::cout<<"norme : "<<p.norme()<<std::endl;
    }
    mais euh... faut juste pas faire çà
    merci pour le contre exemple.
    Comment ferais tu pour cette class?

  15. #35
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Comment ferais tu pour cette class?
    Je ne sais pas faire.

    C'est pour ça que je dis que l'encapsulation est déjà cassée, et qu'on ne peut déjà plus modifier l'implémentation de cette classe. Et donc qu'on se donne beaucoup de mal à donner une apparence encapsulée à une chose qui ne l'est pas (d'où le hypocrite).
    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.

  16. #36
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2008
    Messages : 13
    Points : 14
    Points
    14
    Par défaut
    Personnellement j'utilise _x et _y comme paramètre du constructeur et x et y comme membres.

    Et pour le débat en parallèle, j'encapsule toujours tout, pour la bonne et simple raison que je joue beaucoup avec les exceptions, pour vérifier les paramètre d'entrées et les valeurs de retour avant de les renvoyer.

    C'est loin d'être efficace en performances, mais le débug c'est du gâteau. Et si un réel besoin de performances se fait sentir, alors je retire certaines exceptions.

  17. #37
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je ne sais pas faire.

    C'est pour ça que je dis que l'encapsulation est déjà cassée, et qu'on ne peut déjà plus modifier l'implémentation de cette classe. Et donc qu'on se donne beaucoup de mal à donner une apparence encapsulée à une chose qui ne l'est pas (d'où le hypocrite).
    ok,
    je comprend mieux ce que tu veut dire...
    merci.
    En faite c'est aussi ce type problème qui est produite par les get/set??

    Et ci je la définie comme çà, ça te semble mieux ou y as un aussi un problème??

    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
     
    class CPoint
    {
    	double m_x;
    	double m_y;
    	bool m_calculerNorme;
    	double m_norme;
    public :
    	CPoint(double x,double y) 
    		:m_x(x),m_y(y),m_calculerNorme(true),m_norme(0.)
    	{
    	};
    	const double & initX(const double & x)  
    	{
    		m_calculerNorme = true;
    		m_x = x;
    		return m_x;
    	}
    	const double & x() const 
    	{
    		return m_x;
    	}
     
    	const double & initY(const double & y)  
    	{
    		m_calculerNorme = true;
    		m_y = y;
    		return m_y;
    	}
     
    	const double &y() const
    	{
    		return m_y;
    	}
     
    	const double & norme()
    	{
    		if (m_calculerNorme)
    		{
    			std::cout<<"oui :";
    			m_norme = sqrt(x()*x()+y()*y());
    			m_calculerNorme = false;
    		}
    		return m_norme;
    	}
    };

  18. #38
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Je ne vois pas trop ce que tu as voulu faire... En particulier, en quoi ta solution diffère de get/set classiques ? (à part le retour de const double au lieu dans un cas d'un retour par copie, et dans l'autre d'un void, mais dont j'ai du mal à cerner l'intérêt).

    Dans ce cas là, il peut y avoir effectivement un traitement supplémentaire lors du "set", qui peut avoir un intérêt (même si en pratique, l'intérêt est souvent limité). Il n'empêche que au sens philosophique du terme (et non plus au sens technique, comme avant), la donnée n'est pas vraiment encapsulée pour l'utilisateur final, qui peut voir la classe comme une agrégation de données plus que comme un type à part entière.

    C'est pour ce genre de chose que j'aime bien la notion de propriété, qui permet dans un premier temps de mettre la valeur en public, puis dans le cas hyper improbable où on a besoin d'en faire plus permet de remplacer ça par une fonction, sans que ça n'impacte le code utilisateur de la classe. Mais ça n'existe pas en C++.
    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. #39
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je ne vois pas trop ce que tu as voulu faire... En particulier, en quoi ta solution diffère de get/set classiques ?
    a par les noms je t'avoue que je ne sais pas. J'essaie de comprendre. Sur un autre thread je comprend que les get/set sont mauvais
    http://www.developpez.net/forums/sho...t=87387&page=4
    d'où un nom un different...

    Dans ce cas là, il peut y avoir effectivement un traitement supplémentaire lors du "set", qui peut avoir un intérêt (même si en pratique, l'intérêt est souvent limité). Il n'empêche que au sens philosophique du terme (et non plus au sens technique, comme avant), la donnée n'est pas vraiment encapsulée pour l'utilisateur final, qui peut voir la classe comme une agrégation de données plus que comme un type à part entière.
    C'est à dire que dans ce cas, c'est la définition de la class qui pose le problème d'encapsulation???
    si on utilise un tableau de deux entiers, cela n'as aucun intérêt de faire des get/set aussi?

    Pour Qt, les get/set ont beaucoup d'intérêt pour faire du pimpl, d'où souvent un accésseur const et non const.
    par exemple QImage donne ces deux getter :
    const uchar * bits () const :donne directement le buffer

    uchar * bits () : va vérifier que la mémoire n'est pas partagé entre plusieurs QImage et si oui, recopié la memoire avant de donner le buffer

  20. #40
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Bonjour à tous ! J'aime beaucoup ce sujet ! Et les articles que Luc a cité sont très intéressants.

    Toutefois, comme je suis un novice influençable, ça m'a mis le doute :

    Si je construis une classe Complex toute bête pour représenter un nombre complexe et faciliter les calculs sur ces nombres, on est bien d'accord que je dois mettre mes membres re et im en public ?
    Car contrairement aux cas évolués cités dans les articles donnés par Luc, je ne peux pas demander à ma classe complexe de faire tout le boulot pour moi, dans la mesure où je vais travailler avec des tableaux de Complex plus qu'avec les objets Complex eux-mêmes, et que ce qui m'intéresse c'est donc les 2 valeurs qu'ils contiennent.

    Mais dans ce cas, l'intérêt d'utiliser un objet c'est essentiellement de pouvoir redéfinir les opérateurs, pas d'encapsuler.

    Est-ce que j'ai tenu le bon raisonnement après avoir lu tous vos posts, ou bien suis-je à côté de la plaque ?

    Voilà, petite question de débutant qui s'immisce dans votre discussion
    Merci et bonne journée !

    Raphaël

Discussions similaires

  1. Réponses: 1
    Dernier message: 10/02/2015, 08h21
  2. Ninject Constructeur sans le nom du parametre
    Par mariox dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 05/10/2012, 09h34
  3. Réponses: 7
    Dernier message: 27/05/2011, 17h58
  4. Comment passer des parametres au constructeur d'un service?
    Par jnc65 dans le forum Windows Communication Foundation
    Réponses: 2
    Dernier message: 06/08/2009, 20h41
  5. Recuperation du nom des parametres
    Par Sebastien_INR59 dans le forum Général Java
    Réponses: 16
    Dernier message: 13/10/2007, 23h28

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