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

Contribuez C++ Discussion :

Le langage D


Sujet :

Contribuez C++

  1. #61
    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
    Citation Envoyé par metagoto Voir le message
    Y a un truc que je n'ai pas compris par rapport au LSP et les hiérarchies basées sur une super classe Objet (que ce soit forcé ou non par le langage lui même). Je ne dis pas que koala01 affirme ce qui va suivre, je profite juste de son post pour rebondir sur ce genre d'argument qu'on rencontre, et qui prétend:

    "Les hiérarchies qui s'appuient invariablement sur une base class de type Objet ne respectent pas le LSP."

    Or, la def du LSP:


    Premièrement, selon moi, le LSP concerne avant toute chose les designers et implémenteurs de langages. Soit leurs systèmes de types autorisent le LSP, soit ils ne l'autorisent pas.

    Deuxièmement, sans une analyse "behaviorale" d'un programme , on ne peut rien dire quant à une violation du LSP. On ne peut donc rien dire si la seule chose qu'on sait est "tout dérive de Objet".

    Me fourvoie-je ?
    Le fait est que, pour moi, en tout cas, la conception n'a réellement de sens et d'utilité que... parce qu'elle trace un chemin pour l'implémentation...

    Mais la conception reste, malgré tout, selon moi une nécessité absolue:

    Il ne s'agit, bien sur, que de mon point de vue, mais, selon moi, il est mauvais et dangereux de vouloir dissocier le processus de conception de celui de l'implémentation:

    ils prennent tous deux place dans un processus qui commence avec la demande d'un client "je voudrais une application qui..." et qui s'achève (plus ou moins, mais il faut encore considérer le problème de la maintenace ) avec la livraison de l'application demandée, le premier devant "ouvrir et baliser la voie" pour que le second puisse s'envisager sereinement.

    Si tu te trouve une fois dans une situation dans laquelle il t'est impossible d'implémenter ce qui a été conçu, tu fera l'effort de t'adapter.

    Si tu te trouve quasiment systématiquement dans une situation dans laquelle il t'est impossible d'implémenter ce qui a été conçu, tu va très rapidement (être tenté de) décréter que "la conception ne sert à rien" ou que "c'est une perte de temps" et renoncer à y recourir...

    Or, ce forum et la vie de tous les jours fourmillent d'exemples qui tendent à prouver toute l'utilité de la conception et les risques encourus lorsque l'on n'y a pas apporté une "attention suffisante".


    LSP ne s'applique pas uniquement entre deux niveaux (entre la classe mère et son héritière directe), mais, aussi (et surtout ) sur l'ensemble des niveaux de la hiérarchie d'héritage publique...

    C'est à dire que, pour le respecter, une propriété valide pour l'arrière-arrière-arrière-arrière-grand mère d'une classe doit l'être également pour son arrière-arrière-arrière-arrière-petite fille.

    La conséquence directe étant que, tu dois pouvoir "sans te poser de question" décider d'utiliser n'importe quelle classe "ancêtre" comme type à utiliser pour créer une collection d'objets, et que tu dois pouvoir y placer et utiliser (même si c'est en étant limité à l'interface de la classe ancêtre) ... n'importe quelle objet qui en dérive de manière directe ou indirecte.

    Et ce que je reproche aux langages "tout objet" (bien que je sache parfaitement faire avec), c'est que, oui, on peut dire de n'importe quoi que "c'est un objet", mais qu'il est, surtout si l'on en reste au niveau de l'étude du langage et que l'on ne peut donc, a priori, pas déterminer l'usage qui sera fait de celui-ci, impossible de déterminer un ensemble de propriétés qui, quoi qu'il arrive, quel que soit le type de l'objet créé, représentera le "plus petit ensemble" de propriétés correctes et valides du point de vue de LSP...

    En effet, si tout dérive de manière (très certainement) indirecte de la classe Object (quelle que soit l'orthographe choisie), tu es susceptible de placer un objet de type voiture (qui dérive de véhicule à moteur, qui dérive de véhicule, qui dérive de matière inorganique, qui dérive d'objet) et un objet de type pomme (qui dérive de fruit, qui dérive de matière organique, qui dérive d'objet) dans une même collection basée sur le type Object...

    Or, j'ai beau chercher, je ne vois pas d'ensemble de propriétés communes entre une pomme et une voiture...

    Cela n'est qu'un exemple, mais je pourrais le reproduire avec la très grosse majorité des types que l'on est susceptible de vouloir créé
    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. #62
    Membre éclairé Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Points : 845
    Points
    845
    Par défaut
    Citation Envoyé par koala01 Voir le message
    LSP ne s'applique pas uniquement entre deux niveaux (entre la classe mère et son héritière directe), mais, aussi (et surtout ) sur l'ensemble des niveaux de la hiérarchie d'héritage publique...
    Oui bien sur, on parle de hiérarchie a N niveaux.

    Citation Envoyé par koala01 Voir le message
    En effet, si tout dérive de manière (très certainement) indirecte de la classe Object (quelle que soit l'orthographe choisie), tu es susceptible de placer un objet de type voiture (qui dérive de véhicule à moteur, qui dérive de véhicule, qui dérive de matière inorganique, qui dérive d'objet) et un objet de type pomme (qui dérive de fruit, qui dérive de matière organique, qui dérive d'objet) dans une même collection basée sur le type Object...

    Or, j'ai beau chercher, je ne vois pas d'ensemble de propriétés communes entre une pomme et une voiture...
    Certes, mais tout dériver de Object ne suffit pas à dire qu'on ne respecte pas le LSP. C'est ça le coeur de mon interrogation.
    Après, je ne dis pas qu'une telle hiérarchie est meilleur qu'une autre.

  3. #63
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Remarque, on peut dire la même chose de void*.
    Contient-elle seulement des fonctions membres, cette classe Object ?

    Edit: Pour D 1.0 j'ai trouvé ça :
    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
     
    class Object;
        All D class objects inherit from Object.
     
        void print();
            Converts Object to human readable text and writes it to stdout.
     
        char[] toString();
            Convert Object to a human readable string.
     
        uint toHash();
            Compute hash function for Object.
     
        int opCmp(Object o);
            Compare with another Object obj.
     
            Returns:
            this < obj 	< 0
            this == obj 	0
            this > obj 	> 0
     
     
        int opEquals(Object o);
            Returns !=0 if this object does have the same contents as obj.
     
        static Object factory(char[] classname);
            Create instance of class specified by classname. The class must either have no constructors or have a default constructor.
     
            Returns:
            null if failed
    http://www.digitalmars.com/d/1.0/phobos/object.html


    Et pour D 2.0 :
    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
     
    class Object;
        All D class objects inherit from Object.
     
        string toString();
            Convert Object to a human readable string.
     
        hash_t toHash();
            Compute hash function for Object.
     
        int opCmp(Object o);
            Compare with another Object obj.
     
            Returns:
            this < obj 	< 0
            this == obj 	0
            this > obj 	> 0
     
        equals_t opEquals(Object o);
            Returns !=0 if this object does have the same contents as obj.
     
        static Object factory(string classname);
            Create instance of class specified by classname. The class must either have no constructors or have a default constructor.
     
            Returns:
            null if failed
    http://www.digitalmars.com/d/2.0/phobos/object.html
    Un peu moins pire (le print() en moins), mais bon…
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  4. #64
    Débutant
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Points : 176
    Points
    176
    Par défaut
    Le C++ ne se fera jamais remplacer. il évoluera.

  5. #65
    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
    Citation Envoyé par metagoto Voir le message
    Oui bien sur, on parle de hiérarchie a N niveaux.



    Certes, mais tout dériver de Object ne suffit pas à dire qu'on ne respecte pas le LSP. C'est ça le coeur de mon interrogation.
    Après, je ne dis pas qu'une telle hiérarchie est meilleur qu'une autre.
    Attention, je tiens à préciser que je n'ai jamais dit qu'une hiérarchie basée sur une classe de base unique ne respectait pas LSP...

    J'ai bien dit (c'était le sens de ma phrase) qu'une telle hiérarchie prenait, à mon sens, certaines libertés par rapport à LSP.

    Et, justement, je me disais que je n'étais pas vraiment allé jusqu'au bout de mon raisonnement... et tu me donne une occasion "unique" de le poursuivre

    Nous sommes donc d'accord sur ce qu'implique LSP, et sur le fait qu'il s'applique aux N niveaux d'héritage

    Or, le seul ensemble de "propriétés communes" (c'est tout le sens de LSP) que l'on puisse trouver afin de décider (en respectant LSP) de créer une classe ancêtre commune à toutes les autres est... un ensemble vide.

    Autrement dit, la classe Object (ou quelle que soit son orthographe) ne fournirait aucun service serait composée plus ou moins comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Object
    {
        public:
            /* même pas besoin de définir un constructeur, celui fournit par
             * le compilateur suffit
             */
            virtual ~Object() /* =0   si on veut s'assurer que la classe en soit
                               * pas instanciée en l'état
                               */;
    };
    Si tu y réfléchi, tu ne peux simplement rien faire de l'objet, à par décider de le détruire (tu me dira peut être que ce n'est déjà pas "si mal" ).

    Mais la conséquence directe, c'est que tu ne peux pas envisager d'utiliser concrètement l'instance d'une classe dérivée de Object sans... passer par un downcast...

    Or, c'est là que le bât blesse: si j'admet que le downcast est *parfois* intéressant / utile / nécessaire, j'estime qu'il est mauvais de forcer l'utilisateur à l'utiliser de manière systématique car, dans certains cas, cela force l'utilisateur à mettre en place, par exemple, un pattern "chaine de responsabilités", et donc à complexifier le desing de l'application bien plus que ce qu'il aurait été nécessaire si l'héritage de Object n'avait pas été effectué (forçant l'utilisateur à créer une collection d'objets pris dans le sens moins "générique").

    De plus, l'héritage d'une classe commune présente un autre effet de bord, assez particulier: celui de "déporter" une série de responsabilités.

    Imaginons une collection d'objets.

    Normalement, la collection est sensée savoir quel type d'objet concrets elle doit accepter et renvoyer:

    La responsabilité d'accepter d'ajouter un objet à la collection sur base de la cohérence de type devrait, normalement, échoir à... la collection...

    De même, lorsque l'on accède à un élément de la collection, nous sommes en droit d'obtenir un objet, à tout le moins, utilisable...

    Or, si on crée une collection de Object, non seulement, nous disons à la collection "tu peux tout accepter, y compris de mettre une pomme à coté d'une voiture", mais, en plus, nous déportons la responsabilité de cohérence de type vers la fonction qui devra manipuler la collection... A charge de l'utilisateur de veiller à ce que les types manipulés lors de l'insertion ou de la récupération d'éléments soit cohérent.

    A l'insertion, nous pouvons assurer une certaine cohérence de type en décidant d'insérer non pas des instances de Object, mais plutôt des instances de VehiculeAMoteur (incluant certains bateaux, des camions, des voitures et... des trottinettes à moteurs)

    A l'utilisation de la collection, ou bien nous nous reposons sur le fait que l'insertion a assuré une certaine cohérence des données (... en espérant que c'est bien le cas), ou bien, nous préférons quand même vérifier que le downcast a réussi, mais, quoi qu'il en soit, nous devons downcaster l'Object récupéré en, par exemple, VehiculeAMoteur, afin de pouvoir "ratisser large" et manipuler certains bateaux, des camions, des voitures ou... des trottinettes à moteurs...

    Au passage, je signale qu'il y aurait sans doute également un problème de conception si, l'on décidait de manipuler une collection d'instances de type VehiculeAMoteur alors que l'on souhaite limiter le type aux seules voitures car une même cause aura les même effets: nous devrons downcaster chaque élément avant de pouvoir l'utiliser

    Or, justement, LSP a, entre autre, comme conséquence de s'assurer que, quel que soit le type parent que tu décidera de prendre comme base lorsque tu crée une collection, tu puisse utiliser l'interface publique de ce type pour manipuler les éléments de cette collection sans "te poser de question"...

    Et il faut avouer que, non seulement, il n'est pas cohérent de permettre (comme le fait la classe Object) de placer des pommes et des voitures dans une même collection, mais, en plus, que l'interface publique de la classe Object est - définitivement - trop légère pour être d'une quelconque utilité.

    Voilà en quoi j'estime que la philosophie du "tout objet" prend des liberté par rapport à LSP.
    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

  6. #66
    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
    Citation Envoyé par Florian Goo Voir le message
    Remarque, on peut dire la même chose de void*.
    Contient-elle seulement des fonctions membres, cette classe Object ?

    Edit: Pour D 1.0 j'ai trouvé ça :
    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
     
    class Object;
        All D class objects inherit from Object.
     
        void print();
            Converts Object to human readable text and writes it to stdout.
     
        char[] toString();
            Convert Object to a human readable string.
     
        uint toHash();
            Compute hash function for Object.
     
        int opCmp(Object o);
            Compare with another Object obj.
     
            Returns:
            this < obj 	< 0
            this == obj 	0
            this > obj 	> 0
     
     
        int opEquals(Object o);
            Returns !=0 if this object does have the same contents as obj.
     
        static Object factory(char[] classname);
            Create instance of class specified by classname. The class must either have no constructors or have a default constructor.
     
            Returns:
            null if failed
    http://www.digitalmars.com/d/1.0/phobos/object.html


    Et pour D 2.0 :
    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
     
    class Object;
        All D class objects inherit from Object.
     
        string toString();
            Convert Object to a human readable string.
     
        hash_t toHash();
            Compute hash function for Object.
     
        int opCmp(Object o);
            Compare with another Object obj.
     
            Returns:
            this < obj 	< 0
            this == obj 	0
            this > obj 	> 0
     
        equals_t opEquals(Object o);
            Returns !=0 if this object does have the same contents as obj.
     
        static Object factory(string classname);
            Create instance of class specified by classname. The class must either have no constructors or have a default constructor.
     
            Returns:
            null if failed
    http://www.digitalmars.com/d/2.0/phobos/object.html
    Un peu moins pire (le print() en moins), mais bon…
    Je me doute que, au niveau de la classe Object, de nombreuses fonctions ne sont pas définies, ou qu'elles le sont de manière arbitraires...

    Mais, si l'on ne fait que regarder l'interface de cette classe, cela signifie qu'il est possible de comparer une pomme à une voiture, et qu'il est possible d'obtenir une chaine de caractères basée sur l'objet.

    Je suis désolé, mais, à mon sens, il n'y a, conceptuellement parlant, aucune cohérence ni à vouloir effectuer une telle comparaison, ni à vouloir obtenir une telle chaine de caractères.

    Après tout, comme voulez vous convertir une pomme ou une voiture en chaine de caractères "humainement lisible" en "vroum" et en "miam"

    [EDIT]J'oubliais: void* n'est pas une classe... c'est un objet de type pointeur dont le type est indéterminé...

    Et je suis également contre toute utilisation de ce type de pointeur
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #67
    Membre éclairé Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Points : 845
    Points
    845
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Attention, je tiens à préciser que je n'ai jamais dit qu'une hiérarchie basée sur une classe de base unique ne respectait pas LSP...
    Ah ben voila, tu pouvais t'arrêter là

    Ma question initiale dans ce post était candide, et ne se focalisait pas uniquement sur le c++.

    Alors sinon, oui je suis d'accord avec toi pour le reste de ton argumentation -dans le cadre du c++.

    Par rapport à D et le membre int opCmp(Object o) de la classe Object, j'ai envie de dire: pourquoi pas! Il faudra juste s'assurer qu'un type dérivé de Objet (sur N niveaux) ne brise pas le LSP pour ce membre et ses siblings.

  8. #68
    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
    Citation Envoyé par metagoto Voir le message
    Ah ben voila, tu pouvais t'arrêter là
    Tu aurais au moins pu repsecter mon post, et prendre le paragraphe suivant, qui est à mon sens bien plus important
    Ma question initiale dans ce post était candide, et ne se focalisait pas uniquement sur le c++.

    Alors sinon, oui je suis d'accord avec toi pour le reste de ton argumentation -dans le cadre du c++.
    Le fait est que je ne me focalise pas uniquement sur C++, mais bien sur deux principes de programmation de manière générale que j'estime des plus importants:
    • La règle de la responsabilité unique, qui a une portée tout à fait générale, et, au sujet de laquelle je démontre, effectivement, qu'une optique "tout objet" a tendance à mettre à mal
    • Le principe de substituabilité de liskov, pour lequel il y a une très forte corrélation avec la responsabilité unique, et avec lequel j'estime qu'une optique "tout objet" tend à prendre des libertés

    Regarde ce qui se fait en java: quand tu dispose d'une collection (quel qu'en soit le type), tu dois downcaster l'élément de la collection afin de pouvoir l'utiliser "sous sa forme la plus dérivée" (qui est généralement sa forme la plus utile)...

    La seule présence de ce downcast montre, pour "naturel" qu'il puisse sembler, à l'évidence, d'autant plus qu'il est systématique, que les concepteurs de java ont "fait fausse route" en décidant de présenter une collection permettant de maintenir ensemble des instances dérivées de Object...

    De même, la fonction toString a pour comportement par défaut de fournir une chaine contenant... l'adresse de l'objet...

    C'est, quelque part, normal dans le sens où, autrement, l'utilisateur aurait été tenu de redéfinir cette fonction y compris pour les types pour lesquels une telle fonction est inutile / inopportune, mais elle montre clairement que, effectivement, LSP n'est pas respecté en profondeur car on ne peut pas dire que la propriété toString de la classe Object (dont on peut, soit dit en passant déjà se poser la question de la validité pour la classe Object) soit, effectivement, valide pour les classes qui en dérivent...

    Maintenant, il ne faut pas croire que je ne vise ici que java: je vise, de manière générale, tous les langages utilisant un principe similaire et, au delà, toute conception qui tendrait à mettre un tel principe en oeuvre
    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

  9. #69
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par koala01 Voir le message
    J'oubliais: void* n'est pas une classe... c'est un objet de type pointeur dont le type est indéterminé...

    Et je suis également contre toute utilisation de ce type de pointeur
    Je faisais en fait référence à la soi-disante illégitimité de créer des agrégats d'Object :
    En effet, si tout dérive de manière (très certainement) indirecte de la classe Object (quelle que soit l'orthographe choisie), tu es susceptible de placer un objet de type voiture (qui dérive de véhicule à moteur, qui dérive de véhicule, qui dérive de matière inorganique, qui dérive d'objet) et un objet de type pomme (qui dérive de fruit, qui dérive de matière organique, qui dérive d'objet) dans une même collection basée sur le type Object...
    Mais j'aurais plutôt dû parler de Boost.Any, qui est un void* plus safe.
    Je n'ai personnellement jamais eu à me servir de ça, mais le fait qu'une telle chose existe dans Boost est bien la preuve qu'un tel besoin existe. Et sa légitimité est enforcée par les quelques gourous qui peuplent le comité de validation !

    De ce point de vue, Object serait un Boost.Any natif.

    Pour le reste nous sommes d'accord, rien ne justifie selon moi qu'Object possède la moindre fonction membre…
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  10. #70
    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
    Citation Envoyé par Florian Goo Voir le message
    Je faisais en fait référence à la soi-disante illégitimité de créer des agrégats d'Object :


    Mais j'aurais plutôt dû parler de Boost.Any, qui est un void* plus safe.
    Je n'ai personnellement jamais eu à me servir de ça, mais le fait qu'une telle chose existe dans Boost est bien la preuve qu'un tel besoin existe. Et sa légitimité est enforcée par les quelques gourous qui peuplent le comité de validation !

    De ce point de vue, Object serait un Boost.Any natif.
    il y a bien sur, et c'est quelque part l'objectif de boost.Any, parfois nécessité de pouvoir utiliser un type donné d'objet comme s'il s'agissait d'un autre plus ou moins compatible dans sa sémantique.

    En ce sens, avoir la possibilité de disposer tantôt d'une chaine de caractères, tantôt d'un entier ou d'un double, à l'instar de ce que fait boost.any est louable.

    Mais il reste de la marge entre cette optique adaptée à certaines situations particulières (même si elles sont, en définitive, assez communes) et l'optique qui consiste à estimer que, quel que soit le type manipulé, il puisse être considéré comme compatible avec n'importe quel autre.

    Or, c'est justement l'optique suivie, en définitive, par les langages qui placent, d'une manière ou d'une autre, une classe Object en haut de la hiérarchie d'héritage.

    Autrement dit: permettre une telle substituabilité dans des cas bien déterminés, oui, généraliser cette substituabilité quelles que soient les circonstances, non
    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

  11. #71
    Invité
    Invité(e)
    Par défaut
    Bonjour, j'utilise le D depuis maintenant 2 ans.

    Je m'en sers pour mes projets amateurs et quand j'ai besoin de petits outils/scripts au boulot (surtout traiter des gros fichiers binaires, là où Perl n'est pas très pratique).

    Je trouve qu'il règle quelques problèmes de C++ génants:
    - vitesse de compilation
    - fonction imbriquées manquantes
    - templates durs à écrire et à comprendre
    - niveau très hétérogène du code C++ en circulation
    - pas de propriétés
    - pléthore de smart pointers et classes String différents...

    Il y a un autre problème qui m'énerve particulièrement avec C++: la quantité de chose à faire pour refactorer quelque chose pousse (inconsciemment ?) à ne pas refactorer, pour aller plus vite. Dans D les fonctions imbriquées, la disparition des headers et la compilation plus rapide apporte quelque chose de mieux à mon avis. J'ai aussi constaté que j'étais beaucoup plus productif en D qu'en C++ à cause de tout ces facteurs cumulés.

    Par contre, D vient avec un lot de problèmes assez importants, surtout du côté de l'environnement, qui ont été assez bien résumés ici et . Je rajouterais aussi qu'il n'est pas si facile d'apprendre le D, le langage est assez mouvant et la barrière à l'entrée peut en rebuter beaucoup. Il n'est pas rare de devoir écrire un binding car il n'existe pas...

    Quand au problème de la classe mère Object, je pense que c'est un faux problème. Comme le C#, D fait la séparation entre les "struct" qui sont analogues aux structures C (rien de caché) et les "class" qui contiennent d'office un pointeur vers la TMV et un intrinsic_ptr. On donc est pas obligé de payer pour quelque chose qu'on utilise pas.


    En résumé: D me semble indiqué pour des projets amateurs, pas pour des projets professionnels pour le moment.

    Sous-forum sur D: http://www.developpez.net/forums/f11...es-langages/d/

  12. #72
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 264
    Points : 725
    Points
    725
    Par défaut
    Je connais pas boost.Any mais en D2, l'équivalent, ça serait pas plutôt le type Variant ?

    http://www.digitalmars.com/d/2.0/pho...d_variant.html

    @Koala : Ce que tu dis sur les collections d'objets se tient pour des langages comme Objective-C ou Java, mais je te rappellerai juste que D est un langage multiparadigme, tout comme le C++.

    Tu n'es absolument pas obligé de faire de l'objet en D, et les collections à base de templates existent aussi en D. Tu n'as donc pas besoin de downcaster et le compilateur est tout à fait en mesure de vérifier que tu ne mélanges pas les pommes et les voitures.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    List!(Pomme) pommes = new List!(Pomme);
    pommes.add(new Voiture); // Erreur à la compilation
    "By and large I'm trying to minimize mentions of D in C++ contexts because it's as unfair as bringing a machine gun to a knife fight." - Andrei Alexandrescu

  13. #73
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Je connais pas boost.Any mais en D2, l'équivalent, ça serait pas plutôt le type Variant ?
    Je dirais que l'équivalent en C++ de Variant serait… Boost.Variant .
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  14. #74
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 264
    Points : 725
    Points
    725
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    Je dirais que l'équivalent en C++ de Variant serait… Boost.Variant .
    Au temps pour moi alors.

    @ponce : Je suis rassuré de voir que mon avis est partagé par d'autres personnes au sein de la communauté D.
    "By and large I'm trying to minimize mentions of D in C++ contexts because it's as unfair as bringing a machine gun to a knife fight." - Andrei Alexandrescu

  15. #75
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par ponce Voir le message
    Je trouve qu'il règle quelques problèmes de C++ génants:
    - vitesse de compilation
    Là, je ne peux rien dire - je peux même prédire que ça ne va pas aller en s'arrangeant (du au modèle de compilation du C++).
    Citation Envoyé par ponce Voir le message
    - fonction imbriquées manquantes
    Faux débat. Les fonctions imbriquées ne sont utiles que si on a pas la possibilité d'écrire des fonctions anonymes (ce qui vient dans le futur standard). Dans le standard courant, il est tout à fait possible de créer une classe dans une fonction, et donc de créer autant de fonction imbriquées qu'on le souhaite - je reconnait toutefois que c'est tiré par les cheveux.
    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
     
    int main(int ac, const char* argv[])
    {
      struct internal
      {
        static bool handle_command_line(int ac, const char* argv[]) { ... }
        static void print_usage(const char* process_name) { ... }
      };
     
      if (!internal::handle_command_line(ac, argv))
      {
        internal::print_usage(argv[0]);
        return -1;
      }
     
      return 0;
    }
    Citation Envoyé par ponce Voir le message
    - templates durs à écrire et à comprendre
    Meuh non.
    Ah si. En même temps, les template sont plus destinés aux créateurs de librairies qu'aux développeurs d'applications. Mais je le concède, ils peuvent être complexe à comprendre.
    Citation Envoyé par ponce Voir le message
    - niveau très hétérogène du code C++ en circulation
    C'est vrai dès que tu as du code en liberté. Le C++ n'est ni plus ni moins touché que les autres langages.
    Citation Envoyé par ponce Voir le message
    - pas de propriétés
    Qui n'ont de toute façon strictement aucune raison d'être dans le cadre d'une architecture orientée objet, donc ça n'est pas catastrophique.
    Citation Envoyé par ponce Voir le message
    - pléthore de smart pointers et classes String différents...
    La classe std::basic_string est standardisée - c'est donc la seule à utilisée, à moins d'une contre-indication liée à un framework quelconque (les coupables : Qt, MFC, ... principalement pour des raisons historiques, ces framework datant souvent d'une époque ou les compilateurs ne respectait pas le standard de 98). Les classes du TR1 (héritée de boost) présentent les smart pointer qu'il faut. Elles ont été intégrée au futur standard C++ - donc elles sont normalisées aussi.

    Je ne vais pas dire que le C++ n'a pas, en tant que langage, des problèmes importants (parce que dieu sait qu'il en a). Certains des points que tu soulèves ont leur importance, par contre, d'autre sont quand même des faux problèmes.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  16. #76
    Débutant
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Points : 176
    Points
    176
    Par défaut
    +1 pour l'ensemble des faux problèmes mis en exergue

  17. #77
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    Je n'aurais pas mis la plupart des problèmes la, mais pour la métaprog, c'est vraiment être de mauvaise foie que de ne pas vouloir voir le problème en C++.

    Oui, on peut en faire, oui on peut en faire des trucs sympa, mais c'est absolument mal pensé et relativement difficile à mettre en œuvre.

    Rien que les static if, les CTFE ou les mixins, ou simplement de pouvoir templater sur n'importe quoi (string, float, etc . . .) c'est simplement des fonctionnalités de base qu'on aimerait bien retrouver en C++.

    Par exemple, impossible d'implémenter de façon simple des fonction swizzle en C++ sur des vecteurs.

    Pour idée, voila ce qu'on fait en D :
    http://h3.team0xf.com/ctrace/
    http://www.99-bottles-of-beer.net/language-d-1212.html
    http://www.dsource.org/projects/ddl/...k/meta/regex.d

  18. #78
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Oui, on peut en faire, oui on peut en faire des trucs sympa, mais c'est absolument mal pensé et relativement difficile à mettre en œuvre.

    Rien que les static if, les CTFE ou les mixins, ou simplement de pouvoir templater sur n'importe quoi (string, float, etc . . .) c'est simplement des fonctionnalités de base qu'on aimerait bien retrouver en C++.
    A ce que je sache, c'est plutot que ça ne paraissait pas evident jusqu'à ce que les templates soient dispo en C++ et qu'on se rende compte que des if statiques (entre autre seraient terriblement utiles...

  19. #79
    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
    Citation Envoyé par Niark13 Voir le message
    @Koala : Ce que tu dis sur les collections d'objets se tient pour des langages comme Objective-C ou Java, mais je te rappellerai juste que D est un langage multiparadigme, tout comme le C++.

    Tu n'es absolument pas obligé de faire de l'objet en D, et les collections à base de templates existent aussi en D. Tu n'as donc pas besoin de downcaster et le compilateur est tout à fait en mesure de vérifier que tu ne mélanges pas les pommes et les voitures.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    List!(Pomme) pommes = new List!(Pomme);
    pommes.add(new Voiture); // Erreur à la compilation
    A vrai dire, je ne parle pas spécifiquement du D sur ce point, mais plutôt du problème conceptuel que représente l'idée qui consiste à tout faire dériver(de manière plus ou moins implicite) d'une classe unique... ou, de manière générale, trop "générique".

    L'héritage (publique), quel que soit le niveau envisagé permet de faire passer une instance d'une classe dérivée pour une instance de l'une de ses classes mère /ancêtre...

    A ce titre, je salue la fait que D permette de préciser un type d'objet à placer dans une collection (list par exemple) et qu'il fournisse le moyen de vérifier que les objets que l'on tente d'y placer correspondent.

    Par contre, à moins qu'il n'y ait un mécanisme qui soit en mesure d'empêcher la création de collection... d'Objects, rien n'empêchera l'utilisateur d'écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    List!(Object) truc = new List!(Object);
    truc.add(new Voiture);
    truc.add(new Pomme);
     //voire
    truc.add(new list!(Camion) );
    Et ca, c'est un comportement qui ne permettra de s'en sortir qu'à coup de downcasting

    Mais, encore une fois, je fais ce reproche de manière tout à fait générale, et je l'adresse aussi (principalement ) à des langages comme java ou C#
    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

  20. #80
    Membre éclairé Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Points : 845
    Points
    845
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Par contre, à moins qu'il n'y ait un mécanisme qui soit en mesure d'empêcher la création de collection... d'Objects, rien n'empêchera l'utilisateur d'écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    List!(Object) truc = new List!(Object);
    truc.add(new Voiture);
    truc.add(new Pomme);
     //voire
    truc.add(new list!(Camion) );
    Et ca, c'est un comportement qui ne permettra de s'en sortir qu'à coup de downcasting
    Si on ne manipule les éléments de cette list (ou n'importe quel container d'Objects) qu'à travers l'interface Object (voir les posts plus haut) alors je ne vois pas où est le problème... d'autant plus qu'il est permis d'avoir un list de Pomme. On a donc le meilleurs des 2 mondes. Enfin, je vois ça comme ça.
    Après que cela entraine de gros problèmes de conception -par méconnaissance-, j'ai envie de dire, ce n'est pas mon affaire

    Conceptuellement, ça tient la route. C'est l'essentiel, non ?

Discussions similaires

  1. [langage] Je cherche un bon livre ?
    Par Anonymous dans le forum Langage
    Réponses: 13
    Dernier message: 09/04/2003, 13h16
  2. [langage] Comparer Perl avec d'autres langages comme C ?
    Par Anonymous dans le forum Langage
    Réponses: 3
    Dernier message: 10/08/2002, 23h52
  3. [langage] comment créer des fichiers ?
    Par Anonymous dans le forum Langage
    Réponses: 3
    Dernier message: 05/05/2002, 16h33
  4. Comparer des fichiers de données : Quel Langage ?
    Par Anonymous dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 24/04/2002, 22h37
  5. Cours, tutoriels, logiciels, F.A.Q,... pour le langage SQL
    Par Marc Lussac dans le forum Langage SQL
    Réponses: 0
    Dernier message: 04/04/2002, 10h21

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