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 :

property accessor comme en C#


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 79
    Points : 124
    Points
    124
    Par défaut property accessor comme en C#
    ‘yo

    Je suis débutant en CPP (peut être 30h)

    Dans la plupart des langages de programmation, il existe la «notion» de «property»
    par exemple en C# (code fictif: je ne sais pas coder en C#)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Maclass{
    	string nom {
    		set=>{...code a executer si «nom» est modifié…}
    		get=>{...code a executé si «nom» est consulté…}
    	}
    …
    Maclass monobj*;
    monobj.nom="foxz" // appellera la fonction «set»
    print monobj.nom //appellera la fonction «get»
    pourquoi ne pas porter ce concept en CPP?

    Si dessus ma proposition de code.
    (qui marche plutôt bien...)
    A terme la class prop sera une lib.

    Explications du code en fin.
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include <iostream>
     
    using namespace std;
     
    template<class C, typename T>
    class prop{
        public:
            T value;
            typedef T (C::*tdsetter)(T i);
            tdsetter setter;
            typedef T (C::*tdgetter)();
            tdgetter getter;        
     
            C *slf;
            prop(C *v,tdsetter set,tdgetter get){
                setter=set;
                getter=get;
                slf=v;
            }
            operator T(){
                return (slf->*getter)();
            }
            T operator= (T val){
                value=(slf->*setter)(val);
                return value;
            }
            T* operator->(){
                value=(slf->*getter)();
                return &value;
            }  
    };
     
    class C{
        public:
            int cx=0;
    };
     
    class B{
        private:
            int iset(int i){
                cout <<"B::iset"<<endl;
                return i;
            }
            int iget(){
                cout <<"B::iget"<<endl;
                return inttst.value;
            }
            string sset(string s){
                cout <<"B::sset"<<endl;
                return s;
            }
            string sget(){
                cout <<"B::sget"<<endl;
                return strtst.value;
            }
            C cset(C val){
                cout <<"B::cset"<<endl;
                return val;
            }
            C cget(){
                cout <<"B::cget"<<endl;
                return ctst.value;
            }
        public:
            prop<B,int> inttst={this,&B::iset,&B::iget};
            prop<B,string> strtst={this,&B::sset,&B::sget};
            prop<B,C> ctst={this,&B::cset,&B::cget};
    };
     
    int main(int argc, char** argv){
        B b;
        b.inttst=15;
        b.strtst="hello";
        b.ctst->cx=8;
        cout << b.inttst << endl;
        cout << b.strtst->size() << endl;
        cout << b.ctst.value.cx << endl;
    }
    la class C est un test de type de property.
    La class B est la class contenant des property

    ligne):comment
    9) je n’arrive pas a ecrire de usign avec des class functor
    65) on declare 3 property
    prop <class contenante, type>nom={this, $functor_set,$functor_get}
    (j’ai peut être trouvé le moyen de ne pas déclarer la class contenante en passant par un cast que je ne sais pas encore bien faire en CPP)
    on passe le this pour le context de callback (prop::operator doit connaître le this du context en cours)
    (celui qui est passé dans la declaration prop...={this,…]) et concervé dans "self"

    pour le «set» je passe par l’operator=
    pour le «get» je passe par l’operator de «transtypage» (je sais c’est sale mais je n’ai pas trouvé mieux)

    72) affichera «B::iset» et le this sera celui de B::
    74) comme on ne peux pas surcharger l’operator «.» j’utilise l’operator ->
    pour accéder au contenu de C. (bien que b.ctst ne soit pas un pointer)
    (c’est un peu sale mais je n’ai pas trouvé mieux)
    idem pour la fonction strtst.length()… il faut ecrire strtst->length()...
    au finale je sais que les vieux barbus du CPP trouverons ce code totalement unuseful…
    je donne ici ce code a toute fin utile

  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 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Je vois pas trop la "fin utile" de complexifier le code par du template et diminuer le temps de compilation voire d'exécution pour avoir une syntaxe au mieux bancale, plus lourde, de code bloat.
    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 A
    {
    public:
      void SetA(int newA)
      {
        a = newA;
        // Code à exécuter si a est modifié
      }
      int GetA() const
      {
        // Code à exécuter si a est consulté
       return a;
      }
    private:
      int a;
    };
    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 régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 79
    Points : 124
    Points
    124
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Je vois pas trop la "fin utile" de complexifier le code par du template et diminuer le temps de compilation voire d'exécution pour avoir une syntaxe au mieux bancale, plus lourde, de code bloat.
    parce que c'est fun...

    question lourdeur, c'est a discuter... en bloat tu dois rajouter des settruc gettruc a chaque utilisation.
    bon question compilo c'est sur c'est plus lent... (pardon g un 4xI7core 4ghz 32go)
    a priori je pense qu'en terme d'exe ca doit etre la meme chose a un call (+poussiere) pret

    bloat.set(bloat.get()++).... c'est plus leger que prop++ ?
    (2 call) ....... (3 call en mode fleme)

    <saccasm>
    du coup, tu fais comment pour utiliser les vector sans le templating ?
    </saccasm>

    pour la syntax j'ai trouvé le moyen de me debarasser de la declaration de la class contenante dans la declaration du prop
    mais au prix d'un cast que n'aime pas les vieux routier du cpp.

    ca donnerais juste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class B::public props {
    prop<int>mavar={this, (props)&::set,(pros)&::get}
    (lj'y travail...)

    parait qu'il faut utiliser le casting CPP mais je ne trouve pas d'exemple
    qui correspond a mon cas d'utilisation.
    je dois chercher du coté de dynamic_cast toutim non ? ou bien ?

    <saccasm>
    c'est bien dommage d'avoir un langage aussi puissant pour faire du C avec qq poussieres de POO.
    </saccasm>

    peux tu m'aidé pour ecrire l'usign pour mon typedef ?
    je ne trouve pas d'exemple avec un class functor..
    usign tdsetter=void(class::*)(int) ?

    cinqU

  4. #4
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 476
    Points
    11 476
    Billets dans le blog
    11
    Par défaut
    J'ai écrit un code simple qui fait la même chose que ton exemple (KISS) :

    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
    class C{
        public:
            int cx=0;
    };
    class B{
        public:
            int inttst;
            string strtst;
            C ctst;
    };
     
    int main(int argc, char** argv){
        B b;
        b.inttst=15;
        b.strtst="hello";
        b.ctst.cx=8;
        cout << b.inttst << endl;
        cout << b.strtst.size() << endl;
        cout << b.ctst.cx << endl;
    }
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 79
    Points : 124
    Points
    124
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    J'ai écrit un code simple qui fait la même chose que ton exemple (KISS) :
    Okkeeyyy...

    le but d'un property est de déclencher un "évènement"...
    dans mon exemple je ne fais qu'un cout... mais rien n'empêche d'y mettre un code wizz...

    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class  fenetre
     prop<string>title={this, ;.. toutim...}
    déclenchera le "toutin" sur un mafentre.titre="mon titre"...
    comme si tu avais un bloat settile mais sans la "lourdeur" du bloat.


    comme je disais, le concept de property existe dans d'autre langage
    même si je n'ai aucune idée de la freq d'utilisation en C# par ex.
    ca existe... c'est possible de le faire en cpp. ca évite de balader des
    set/get. En surchargeant les operator qui vont bien tu pourra faire
    prop++. avec un bloat il faudra écrire bloat.set(bloat.get()++)...
    moi ca, ca me pique les yeux...

    5u

  6. #6
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 476
    Points
    11 476
    Billets dans le blog
    11
    Par défaut
    Citation Envoyé par foxzoolm Voir le message
    (...) ca evite de ballader des
    set/get. En surchargant les operator qui vont bien tu pourra faire
    prop++. avec un bloat il faudra ecrire bloat.set(bloat.get()++)...
    moi ca, ca me pique les yeux...
    Moi aussi ça me pique les yeux, mais du coup on perd la notion de "service" qu'une classe doit proposer.
    Si on veut que la classe expose le service "incrémente le compteur", on écrit une fonction pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class A
    {
      ...
     
      int incCompteur()
      {
        return bloat++;
      }
    };
    C'est ce qui fait que je pense que les propriétés sont une mauvaise idée (comme les getters/setters), ils font réfléchir en termes de données plutôt qu'en termes de services fournis, et à ce moment passer par des membres publics reste la meilleure solution.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  7. #7
    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 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par foxzoolm Voir le message
    déclenchera le "toutin" sur un mafentre.titre="mon titre"...
    comme si tu avais un bloat settile mais sans la "lourdeur" du bloat.


    comme je disais, le concept de property existe dans d'autre langage
    meme si je n'ai aucune idée de la freq d'utilisation en C# par ex.
    ca existe... c'est possible de le faire en cpp. ca evite de ballader des
    set/get. En surchargant les operator qui vont bien tu pourra faire
    prop++. avec un bloat il faudra ecrire bloat.set(bloat.get()++)...
    moi ca, ca me pique les yeux...

    5u
    Je crois que t'as pas compris ce que code bloat signifie.
    Si écrire toto.setTruc te fatigue, je conseille d'arrêter immédiatement la programmation, ça sera plus simple.
    Si tu aimes tant le C#, fais donc du C#.
    C++ n'a pas non plus de GC, est-ce que ça manque ? Non.
    Tu peux continuer à écrire du mauvais code template totalement inutile, mais sois pas surpris quand on dit qu'il est inutile. Et inutile de te cacher derrière des "ho ça va pas plaire aux dinosaures du C++", parce qu'en fait au mieux on s'en fout royal, mais on va sûrement pas laisser ça comme étant une "bonne pratique".

    c'est bien dommage d'avoir un langage aussi puissant pour faire du C avec qq poussieres de POO.
    Bah fais donc du C++ et non du C with classes, puis on en reparlera.
    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.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    De mémoire, Borland C++ Builder supportait des extensions pour faire des "propriétés" en tant que sucre syntaxique. Mais comme dit plus haut, ça ne sert pas à grand-chose si c'est pour imiter un type POD.

    Les "propriétés" ont plus leur utilité dans un langage qui supporte les interfaces (au sens .NET/Java)), vu que celles-ci n'ont pas le droit d'avoir des variables membres.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

    Informations professionnelles :
    Activité : aucun

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

    De manière générale, on pourrait se dire que

    1- Si le but est de mettre une donnée dans l'accessibilité privée tout en permettant à l'utilisateur d'une classe d'y accéder "sans restriction" (en lecture et en écriture) au travers de fonction getXX et setXXX, il n'y a absolument aucun intérêt à le faire, pour la simple et bonne raison que cela n'améliore absolument pas l'encapsulation.

    En effet, cette pratique présente l'énorme inconvénient de toujours laisser l'utilisateur de la classe responsable de la logique qui permet de déterminer la nouvelle valeur à la donnée, avec le risque -- toujours présent -- qu'il oublie certaines restrictions que la classe impose normalement.

    De plus, on se retrouve alors avec une classe qui ressemblerait à quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MaClass{
    public:
        void setX(int newX){
           m_x = newX;
        }
        int getX() const{
            return m_x;
        }
    private:
        int m_x;
    };
    et qui devrait donc être utilisée sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main(){
        MaClasse mc;
        mc.setX(mc.getX() * 5 ); // où est la certitude que la nouvelle valeur n'est pas excessive par rapport aux restrictions de MaClasse?
    }
    alors que, si la donnée membre avait été publique, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class MaClass{
    public:
        int x;
    };
    nous aurions tout aussi bien pu nous contenter d'une utilisation proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main(){
        MaClasse mc;
        mc.x *=5;
    }
    qui nous aurait évité d'avoir à demander la valeur de x avant de pouvoir la multiplier par cinq dans le but de définir ... la valeur de x

    2- Les langages comme java et C# souffrent d'un problème de conception majeur qui fait pourtant leur force principale: leur gestion de la mémoire repose sur l'utilisation d'un "ramasse miettes".

    De ce fait, leurs interfaces ne peuvent effectivement contenir aucune donnée (pour laquelle l'allocation de la mémoire serait requise), simplement, parce que le ramasse miettes ne peut voir que les données qui émanent de la hiérarchie basée sur la classe Object.

    Or, le but des interfaces est -- justement -- de n'être "relié" à la hiérarchie basée sur la classe Object qu'au "tout dernier moment" (au moment où la classe qui implémente l'interface devient concrète).

    En C++, il est tout à fait possible de créer des classes qui agissent comme des interface, dans le sens où il serait totalement impossible de les instancier si elles ne sont pas "implémentées" au travers d'une classe concrète.

    Il suffit en effet de placer le constructeur et le destructeur dans l'accessibilité protégée (pour que les classes qui en héritent puissent y accéder malgré tout), et le tour est joué.

    Le gros avantage est qu'il n'y a absolument rien qui interdise à ce genre "d'interface" de contenir certaines données requises pour permettre l'implémentation de fonctions.

    En outre, si on utilise l'approche générique (les template) pour ce genre particulier de classe, nous pouvons même éviter de créer des relations qui ne devraient pas forcément exister entre deux classes qui exposent des fonctions similaires dans leurs comportement et qui portent donc ... des noms similaires.

    Par exemple, une interface proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template <typename Base>
    class AgeHoler{
    public:
        int age() const{
            return currentDate().year - year_;
        }
    protected:
        AgeHolder(int year): year_{year}{
        }
        ~AgeHolder() = default;
    private:
        int year_;
    };
    Nous pouvons créer une classe Personne et une classe Voiture qui exposent toutes les deux cette interface sans pour autant qu'il n'y ait de lien "physique" entre les deux classes: ce sont juste des classes qui exposent les même fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Voiture : public AgeHolder<Voiture>{
    public:
        Voiture(int anneeDeConstruction):AgeHolder<Voiture>{anneeDeConstruction}{
        }
    };
    class Personne : public AgeHolder<Personne>{
    public:
        Personne(int anneeDeNaissance):AgeHolder<Personne>{anneeDeNaissance}{
        }
    };
    qui fonctionnera parfaitement, sans créer de lien "artificiel" entre la classe Personne et la classe Voiture.

    De ce fait, étant donné qu'une interface est surtout destinée à exposer un (ou plusieurs) service(s) exprimé(s) au travers d'une (ou plusieurs) fonction(s) devant "baliser" la manière dont les classes seront utilisées, quel serait l'avantage de présenter des "propriétés", à moins que l'on n'essaye de modéliser une base de données (et encore)
    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

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Getters and setters are evil.


    Blague (quoi que...) à part, Qt a un méchanisme de properies qui semblent être pas trop loin de ce que tu cherches : https://doc.qt.io/Qt-5/properties.html

  11. #11
    Membre actif
    Homme Profil pro
    libre
    Inscrit en
    Juin 2019
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Juin 2019
    Messages : 205
    Points : 292
    Points
    292
    Par défaut
    C++ Borland
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    __ property int Count ={read=FCount,write=SetCount,nodefault};

    En C# et en Delphi on utilise les properties dans les structures pour creer des champs de bit qui n'est pas dans ces langages

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    De mémoire, Borland C++ Builder supportait des extensions pour faire des "propriétés" en tant que sucre syntaxique. Mais comme dit plus haut, ça ne sert pas à grand-chose si c'est pour imiter un type POD.
    Citation Envoyé par wheel Voir le message
    en Delphi on utilise les properties dans les structures pour creer des champs de bit qui n'est pas dans ces langages
    en Delphi/ C++ propriétaire, cela va plus loin : le stockage, "default", ... (quoique je n'ai pas testé avec les nouvelles versions qui remplacent leur compilateur C++ propriétaire vétuste par GCC pour avoir du C++ moderne)

    Et d'après moi, c'est surtout lorsque le code crée les fenêtres/ composants en lisant les fichiers .dfm. Parce que dans ces fichiers tu ne modifies que les membres, tu n'appelles pas de méthodes.
    Ces propriétés servent de décorateur (<- le patron de conception)

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 79
    Points : 124
    Points
    124
    Par défaut
    Il n'y a aucune difference entre un bloat et une property (sauce C#).

    A l'exception de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    a.setXXX(a.getXXX()+" wizzz") // pour un bloat
    au lieu 
    a.XXX+=" wizzz" // pour une property
    Dans les 2 cas, les getter/setter seront dans le contexte de l'objet.

    Le langage permet de le faire ?
    Pourquoi s'en priver ?

    Rien n'est vraiment utile, tout est absolument nécessaire...

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par foxzoolm Voir le message
    Il n'y a aucune difference entre un bloat et une property (sauce c#)
    a l'exception de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    a.setXXX(a.getXXX()+" wizzz") // pour un bloat
    au lieu 
    a.XXX+=" wizzz" // pour une property
    ooh que si, qu'il y a une différence.

    A vrai dire, je peux même t'en citer trois, des différences:

    Primo, il y a la différence entre ce qui prendra la forme d'un opérateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type operator + (Type /* const & */ a, Type /* const & b)
    et l'opérateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type & operator +=(Type /* const &*/ b)
    car, avec le premier, un code proche de
    va en réalité nécessiter le passage par une variable temporaire, ce qui donnera un code en réalité proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Type temp = A + B;
    A = temp;
    alors que le deuxième modifiera directement l'opérande de gauche.

    Après, il est vrai qu'il y a des optimisations possibles qui permettent au compilateur de passer outre la création d'une variable temporaire. Cependant, cette élision n'a absolument rien de garanti.

    Deusio : Beaucoup de gens vont croire que leurs données sont correctement encapsulées à la vue d'un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data.setX(data.getX() + XYZ);
    Alors que, en réalité, il n'y a absolument aucune encapsulation là dedans...

    Car ce code va donner la responsabilité du calcul de la nouvelle valeur pour le x de data à l'utilisateur, qui va -- forcément -- faire une connerie à un moment ou à un autre en ce faisant.

    Pour qu'une donnée puisse être considérée comme "correctement encapsulée", il ne suffit pas d'avoir des fonctions get et set. Il faut que l'utilisateur ne doive fournir que les informations qui permettront d'évaluer la nouvelle valeur de la donnée de manière à ce que la cohérence de cette nouvelle valeur puisse être vérifiée au moment du calcul et que la réaction adaptée puisse être appliquée si ce n'est pas le cas.

    Un parfait exemple de structure correctement encapsulée serait -- quoi que l'on en pense -- la structure FILE du C car, si tu veux savoir ce qu'elle contient, tu es bon pour parcourir les fichiers d'implémentation pour retrouver son contenu (après avoir traité des dizaines de macros différentes), et que l'utilisation de cette structure est entièrement gérée par "un certain nombre" de fonctions qui ne laissent pas la possibilité à l'utilisateur de faire une connerie (à moins, bien sur, de fournir des nombres d'éléments aberrant ou de demander la lecture d'informations de type différent que celles présentes dans le fichier).

    Tersio : Ce code donne la fausse idée à l'utilisateur de travailler selon une approche orientée objets à cause de la présence des fonctions membres setX et getX. Ce sentiment étant en outre exacerbé par la (fausse) idée d'avoir des données encapsulées.

    Or, ni la présence de fonctions membres ni l'encapsulation (surtout si elle n'est que de façade, comme c'est le cas ici) ne suffisent pour considérer le fait que l'on travailler selon une approche orientée objets.

    A vrai dire, l'encapsulation (lorsqu'elle est correcte) n'est qu'un bénéfice inné de l'orienté objet, et les fonctions membres n'en sont qu'un détail qui pourrait tout aussi bien être ignoré, car le véritable principe de base de l'orienté objet, celui sans lequel l'orienté objets n'existerait pas, c'est la substituabilité au sens du principe de substitution de Liskov.

    Pour pouvoir réellement considérer que l'on travaille selon une approche orientée objets, il faut donc pouvoir manipuler une donnée "spécialisée" (comme une voiture ou une moto) en " la faisant passer pour " une donnée plus "générique" (comme la notion de "véhicule", dans le cas présent).
    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

Discussions similaires

  1. Réponses: 0
    Dernier message: 22/12/2016, 11h11
  2. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  3. [langage] Comparer Perl avec d'autres langages comme C ?
    Par Anonymous dans le forum Langage
    Réponses: 3
    Dernier message: 10/08/2002, 23h52
  4. Afficher/Masquer un bouton comme IE 6
    Par benj63 dans le forum C++Builder
    Réponses: 3
    Dernier message: 29/07/2002, 13h12
  5. Réponses: 3
    Dernier message: 19/07/2002, 15h01

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