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 :

Méthodes virtuelles (again)


Sujet :

C++

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Citation Envoyé par oodini Voir le message
    Je pense qu'il faudrait que je lise un bon ouvrage qui traite du sujet en profondeur pour bien saisir l'intérêt d'autant se soucier de ces problématiques, et de m'en imprégner.

    Quelqu'un aurait-il des références à me donner ?
    Ma conclusion du moment sur le sujet, c'est que c'est une dichotomie assez artificielle est assez propre au C++ à cause de comment les données transitent en sortie des fonctions (copie ou truc alloué).
    Il n'y a pas de références absolues. J'ai l'impression que les premières choses viennent de Stepanov (mais sans certitudes) qui va plus loin en introduisant les "objets réguliers" (valeur + ordonnables).
    Mes quelques pointeurs sur ces sujets sont, dans le désordre:
    - http://www.angelikalanger.com/Articl...ls/Equals.html (ou quand Java se pose une question proche)
    - http://akrzemi1.wordpress.com/2011/0...onstructor-qa/ (indirectement)
    - http://www.mr-edd.co.uk/blog/another...plicit_vtables (des contournements)
    - http://blog.emmanueldeloget.com/inde...C3%A9placement (des explications)
    - http://akrzemi1.wordpress.com/2012/0...lue-semantics/ (d'autres explications)
    - http://stackoverflow.com/questions/2.../269313#269313
    - http://www.drdobbs.com/cpp/if-c-obje...equa/240146950 (Koenig qui en parle dans un article récent sur le DDJ)

    Coplien a aussi du en parler vu que la FCOC s'applique sur les objets valeurs. Ainsi qu'au travers de l'idiome enveloppe-lettre qui permet de rendre affectables des objets tirés de hiérarchies polymorphes.

    Bref. Après, cette dichotomie aussi artificielle soit-elle, nous permet de disposer de recettes de cuisine prêtes à l'emploi (dans le jardon on dit patterns ou idiomes) en fonction du type de classe que nous sommes en train d'écrire.

    Concernant les conteneurs standards, ils sont légèrement bâtards à mon gout. Syntaxiquement parlant ils se comportent comme des valeurs (copiables), sémantiquement parlant, ils peuvent aussi se comporter comme des entités (car altérables => ils ont une identité propre que l'on utilise régulièrement)
    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...

  2. #42
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En fait, je ne vois pas pourquoi la copie d'une entité serait interdite. Elle doit être régulée c'est sûr (pour éviter les problèmes en cas d'héritage), mais pour moi l'interdire est arbitraire.

    (sauf pour les objets RAII qui servent à gérer une ressource dans le scope; et encore, parfois un comptage de références (intrusif ou non) est préférable à l'interdiction de la copie)
    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.

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Par défaut l'interdire est la bonne solution car:
    1- en pratique on n'en a que rarement besoin (car sémantiquement copier ces classes n'est pas un besoin que l'on éprouvera)
    2- côté code c'est une quantité souvent phénoménale et non triviale de boulot en plus pour avoir un truc sans effet de bords et qui se comportera toujours comme attendu.

    Donc pourquoi perdre 3 jours à chaque fois pour avoir un truc correct que personne n'utilisera jamais ? Moi, je ne vois pas pourquoi autoriser les copies sur les classes entité. C'est de la perte de temps et des risques inutiles, pour personne qui ne s'en servira jamais.
    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...

  4. #44
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Oui, mais ce n'est pas "parce que c'est une entité" que j'interdis la copie, seulement "parce que la copie par défaut n'est pas bonne (fuite de mémoire) et que j'ai la flemme d'écrire un constructeur de copie".

    Mais ce n'est que deux façons différentes d'exprimer la même opinion: La question n'est pas "pourquoi interdire la copie?" mais "pourquoi la permettre?"
    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.

  5. #45
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par r0d Voir le message
    Je crains que cette requête ne reste vaine. Cela fait des mois que je cherche de telles références, et je suis bredouille.

    En fait, dès le début il y a quelque chose qui cloche dans cette histoire: une classe à sémantique de valeur est sensée être immuable.
    1. Qu'est-ce que cela signifie au juste? Qu'elle ne doit être instanciée que sous forme constante? (const Maclasse instance( params ); )
    Non, cela veut dire que les modifications se feront le plus souvent par affectation d'une nouvelle valeur / instance de classe

    Si je reprend l'exemple de la classe point, tu va "simplement" affecter le nouveau point à la variable qui contient l'ancienne valeur, idem pour la classe couleur, pour n'importe quel type primitif ou pour std::string

    Le code que tu mettras en oeuvre sera souvent du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    variable = nouvelleValeur; /* une autre variable, résultat d'un
                                * calcul ou  quelque chose qui 
                                * soit implicitement convertible dans le type adéquat
                                */
    Alors, bien sur, il reste toujours possible d'envisager d'avoir des comportements qui modifient les valeurs internes dans certaines circonstances, comme la fonction append de std::string ou les fonctions d'insertion dans les collections, mais on peut malgré tout parler d'exception à ce sujet (même si cela arrive souvent )

    Par contre, pour les classes ayant sémantique d'entité, on sait d'office que certains comportements modifieront la valeur d'un attribut interne (généralement en effectuant une affectation comme présenté ici ), entre autres actions prises

    Et, surtout, tu ne peux en aucun cas envisager l'affectation pour les instances de ce genre de classe.

    Un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Personne koala("koala01");
    Personne rod("r0d");
    rod = koala;
    serait au mieux incorrect, au pire suicidaire
    2. Concrètement, est-ce que quelqu'un a déjà vu cela? (moi non, mais j'avoue que ça ne démontre rien).
    Moi non plus, mais cela ne démontre rien, en effet (et surtout, c'est sans objet étant donné que je viens de dire que l'idée n'est pas de travailler d'office avec des valeurs constantes, mais que l'immuabilité d'une variable implique "simplement" qu'il y aura affectation d'une nouvelle variable en cas de modification )
    3. Quel peut bien être l'intérêt d'un tel animal?
    On pourrait sans doute en trouver un, mais on parlerait alors sans doute de constante
    Bon, le ton de ce message est un peu agressif, mais c'est juste dans le but faire réagir ceux qui en savent plus. J'ai une intuition: l'utilisation de la classe std::string pourrait peut-être aider à y voir plus clair. Je suis en train d'y réfléchir.
    Justement, la classe string est un excellent exemple.

    De nombreuses utilisations de string vont passer par l'affectation pure et simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::string first("salut");
    std::string second("le monde");
    std::string temp=first;
    std::string secondtemp="salut le monde";
    S'il existe quelques fonctions membres qui modifient l'état interne de la chaine de caractères, c'est essentiellement parce que cela correspond à des services que l'on est en droit d'en attendre, mais ils sont, de manière générale, minoritaires par rapport à l'ensemble des services qui se contentent d'accéder aux données sans les modifier.

    On dit à juste titre qu'il ne faut pas trop s'intéresser, en POO, au détails d'implémentation, et il ne s'agit absolument pas de revenir sur ce point, car je trouve qu'il est important.

    Mais si, dans un but "purement analytique", on observe les détails d'implémentation, on remarquera sans doute une constante:

    Les classes ayant sémantique de valeur vont proposer une très large proportion de comportements en "lecture seule" (comprends: sans modification des détails d'implémentation), alors que les classes à sémantique d'entité proposeront très régulièrement au minimum un comportement de modification par détail d'implémentation (et parfois plusieurs).

    Le nombre de comportement tendant à modifier l'état interne de l'objet sera souvent bien plus important dans une classes ayant sémantique d'entité
    Edit: et je pense aussi qu'il n'est pas raisonnable de considérer que les développeurs java ne comprennent rien à la poo. Je connais des javaistes qui en connaissent bien plus que moi sur le sujet, et de façon générale, le java a aussi ses gourous qui n'ont, à mon avis, rien à envier à ceux du c++.
    Attention, je n'ai pas dit que les développeurs java ne connaisse rien

    Ce serait injuste, non fondé et inutilement agressif

    Par contre, ce que je dis, c'est que la philosophie java favorise le fait que certaines personnes incompétentes puissent avoir un estime d'eux même beaucoup trop haute parce que c'est, selon moi (mais bon, je n'oblige personne à suivre cet avis ) un langage clairement estampillé "idiot-proof"
    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. #46
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    La classe string du C++ est assez bizarre par rapport aux classes String d'autres langages, parce bien qu'elle ait dans la plupart de ses usages une sémantique de valeur, elle n'est pas immuable, ce qui lui confère une part de sémantique d'entité.
    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.

  7. #47
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    En fait, je ne vois pas pourquoi la copie d'une entité serait interdite. Elle doit être régulée c'est sûr (pour éviter les problèmes en cas d'héritage), mais pour moi l'interdire est arbitraire.

    (sauf pour les objets RAII qui servent à gérer une ressource dans le scope; et encore, parfois un comptage de références (intrusif ou non) est préférable à l'interdiction de la copie)
    Parce que, si tu autorise la copie de medinoc, tu ne pourras jamais être sur que les comportements que tu appelles depuis medinoc modifieront bel et bien ... medinoc et non la copie.

    Quand tu rentre dans une logique d'héritage, tu te trouves (dans la grande majorité des cas) face à un besoin d'unicité référentielle qui puisse t'assurer d'agir systématiquement sur un objet clairement défini (entre autre par son adresse mémoire, mais il peut y avoir d'autres approches ).

    Autoriser la copie t'empêche de maintenir cette unicité référentielle, et, partant de là, t'oblige à t'assurer que tout ce qui pourrait arriver aux copies sera bel et bien répercuté sur l'original
    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

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Mais si je fais une copie, je ne veux pas que les modifs sur la copie soient répercutées sur l'original. D'ailleurs, les entités n'étant pas immuables, la première chose que je changerai sur la copie sera probablement son identité.

    vOn est d'accord.
    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. #49
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Oui, mais ce n'est pas "parce que c'est une entité" que j'interdis la copie, seulement "parce que la copie par défaut n'est pas bonne (fuite de mémoire) et que j'ai la flemme d'écrire un constructeur de copie".

    Mais ce n'est que deux façons différentes d'exprimer la même opinion: La question n'est pas "pourquoi interdire la copie?" mais "pourquoi la permettre?"
    Mon raisonnement, dans l'ordre (enfin ... c'est un diagramme en fait)
    héritage => entité
    entité => pas besoin copie
    ressource => copie par défaut pas bonne, voir si pas une entité
    pas besoin copie => j'interdis la copie
    héritage => affectation par défaut infernale à écrire correctement
    copie | affectation - pas bonne | infernale à écrire => j'interdis la copie.

    C'est plein de raccourcis, mais 99% du temps tous sont valables.
    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...

  10. #50
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Mais si je fais une copie, je ne veux pas que les modifs sur la copie soient répercutées sur l'original. D'ailleurs, les entités n'étant pas immuables, la première chose que je changerai sur la copie sera probablement son identité.
    A ce moment là, ce que tu dois mettre en place, ce n'est pas une autorisation de copie, mais la possibilité de cloner tes objets.

    La copie présente un inconvénient majeur: celui de copier tous les attributs, y compris... l'identitiant de ton objet qui est, classiquement, immuable (car toute modification au niveau des données qui permettent d'identifier un objet de manière "unique et non ambigüe" risque de "casser les références croisées" et, au minimum d'occasionner des problèmes de tri).

    Le principe du clônage est de te permettre de n'avoir qu'une "copie partielle" de ton objet d'origine dans le sens où tout ce qui le caractérise peut etre copié si tu le souhaites, à l'exception... de ce qui permet de l'identifier de manière unique et non ambigüe
    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. #51
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    C'est ce que je voulais dire par "réguler" la copie.
    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.

  12. #52
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Citation Envoyé par Neckara
    Je comprend mal ce point là.
    J'ai un entier qui est un nombre, qu'est-ce qui empêche mon entier d'avoir une sémantique de valeur ?
    Mais il A sémantique de valeur!!!
    En fait je sous-entends par "un entier qui est un nombre" que j'ai une classe Entier qui hérite de la classe Nombre, donc en quoi l'héritage empêcherait mon Entier d'avoir une sémantique de valeur.

    Citation Envoyé par Luc Hermitte Voir le message
    c- Ce n'est pas possible dynamiquement. Si le type dynamique de tes objets est IN malgré que leur type réel est ZZ, tu peux faire ce que tu veux, tu ne pourras pas récupérer autre chose qu'un ZZ car tu ne pourras appeler que op+(ZZ, ZZ), (ou ZZ::op+(ZZ)) qui renvoie un ZZ.
    La solution que j'ai proposée ici ne marcherait-elle pas ?

    Citation Envoyé par Luc Hermitte Voir le message
    d- L'héritage n'est pas valide, il viole le LSP. Car la division entière a un résidu (le modulo) que la division des relatifs ne produit pas. D'où que si tu reprends mon exemple tu verras une rupture de contrat sur la réversibilité. On se retrouve avec une fonction dont on change le comportement. Pas bon ça.
    On peut conserver la division "normale" comme comportement par défaut (donc N/N produirais un Q) et ajouter dans N (voir même dans Z) de nouveaux comportement comme le modulo et la division entière dont hériterais tous les fils.

    Citation Envoyé par Luc Hermitte Voir le message
    e- Non, c'est de modéliser les divers ensembles via des templates et des surcharges pour les spécialisations.
    Mais dans ce cas là, il faut fournir des classes abstraites qui serviront d'interface pour savoir ce qu'on a le droit de faire/ce qu'il faut implémenter ie définir les opérations existantes dans certains ensembles.
    Un ensemble B inclus dans l'ensemble C hérite des opérations autorisés dans C, car tout élément de B est un C.
    Par contre le fait d'être dans B va rajouter d'autres comportements.

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    c- Non.
    Car f(Relatif, Relatif) et pas f(Entier, Entier) ni f<T,T>(T,T)
    Hériter sans utiliser le polymorphisme d'inclusion dynamique, il manque des trucs.

    d- C'est une vision partielle qui passe à côté des réels, des complexes, des quaternions, ...

    e- Non pas des classes abstraites. Juste prévoir toutes les opérations possibles grâce aux deux polymorphismes ad'hoc, et écrire les fonctions génériques qui exploitent ces nombres sous forme template (avec polymorphisme paramétrique).
    Le polymorphisme d'inclusion n'est pas utilisable ici.
    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...

  14. #54
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    c- Non.
    Car f(Relatif, Relatif) et pas f(Entier, Entier) ni f<T,T>(T,T)
    C'est à dire ?

    Citation Envoyé par Luc Hermitte Voir le message
    d- C'est une vision partielle qui passe à côté des réels, des complexes, des quaternions, ...
    Je ne comprend pas ce que tu veux dire ici.

    Citation Envoyé par Luc Hermitte Voir le message
    e- Non pas des classes abstraites. Juste prévoir toutes les opérations possibles grâce aux deux polymorphismes ad'hoc, et écrire les fonctions génériques qui exploitent ces nombres sous forme template (avec polymorphisme paramétrique).
    Le polymorphisme d'inclusion n'est pas utilisable ici.
    Je trouve qu'on perds de l'information en utilisant des templates :
    - on ne sait pas quels types de nombres la méthode supporte
    - quand on créé un nouveau type, on ne sait pas ce qu'il doit implémenter.

  15. #55
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    @Neckara: Pour les "entités mathématiques", prenons un exemple simple avec deux classes : real, complex, real héritant de complex. Le problème peut sa voir à travers un seul exemple, imagines un service "dephasing" (lié à complex) l'ensemble des ses entrées c'est donc des réels et il retourne void. Lorsque tu définies ton héritage entre real et complex, tu fais quoi de "dephasing" ? La seul valeur cohérente pour un réel c'est 0 (sinon ce n'est plus un réel), donc tu réduits l'ensemble des valeurs d'entrée possibles, ça rend inutilisable la classe héritée real dans un code prévu pour fonctionner avec complex (c'est quand même l'objectif du polymorphisme).

    Et c'est ça le problème de fond : les ensembles mathématiques s'incluent bien les uns les autres, mais les services associés aux ensembles sont de plus en plus restrictifs. Exprimé mathématiquement, avec A, B, C, D des ensembles, A inclus dans B et C inclues dans D, soit f une fonction de B*D -> B qui représente un service associé à B. Mathématiquement ce service dans A doit être tel que f(A*E) inclue dans A, avec E un ensemble. Et c'est là que le problème arrive :
    -> Mathématiquement, E est (souvent, comme pour "phasing") un sous-ensemble (strict) de D.
    -> En programmation par contrat, les pré-conditions doivent être plus faible : l'ensemble E doit contenir D.

    Ce raisonnement se retrouve avec énormément d’éléments des mathématiques , l'exemple du carré/rectangle ou du carré/losange illustre la même chose. Ceci dit, ce n'est pas un "résultat" systématique, ça dépend de l'utilité de tes classes : si elles sont là pour réellement à manipuler des réels/complexes, c'est problématique, si, par exemple, elles servent à représenter des éléments d'un arbres, ça peut se justifier.


    @Médinoc: Personnellement, j'ai tendance à associer la sémantique d'entité à un opérateur (fictif : il ne sert à rien en pratique (*)) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    bool operator==(const A& lhs, constA& rhs)
    { return &lhs == &rhs; }
    Et d'autre part à considérer que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    A a;
    A b(a);
    assert(a == b);
    Est toujours vrai (**). D'où un résultat un peu étonnant même si on suppose un constructeur de copie valide. Par contre si une "copie" est réalisé par un appel à une fonction "clone" je ne m'attend pas à cette égalité, par contre je m'attend à ce que les deux entités partagent toutes las caractéristiques qui ne font pas leur unicité.


    (*) Il exprime juste la notion d'unicité des entités qu'à exprimé Koala plus tôt dans la discussion.

    (**) Ce second code est une attente naturelle, et quand il n'est pas respecté (comme dans auto_ptr) ça demande une attention particulière à ce qu'on fait.

  16. #56
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Je trouve qu'on perds de l'information en utilisant des templates :
    - on ne sait pas quels types de nombres la méthode supporte
    Avec le C++11, il y a moyen, via std::enable_if et std::is_same.

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Citation Envoyé par Neckara Voir le message
    c- C'est à dire ?

    d- Je ne comprend pas ce que tu veux dire ici.

    e- Je trouve qu'on perds de l'information en utilisant des templates :
    - on ne sait pas quels types de nombres la méthode supporte
    - quand on créé un nouveau type, on ne sait pas ce qu'il doit implémenter.
    Reprends la fonction que je t'avais proposée.
    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
    struct Rationel {....
        virtual Rationel operator/(Rationel const& rhs) const;
    };
    struct Entier : Rationel {
        // et oui, nous sommes obligés de garder la même signature... 
        // même si cela n'a aucun sens
        virtual Rationel operator/(Rationel const& rhs) const;
        // c'est pourquoi je demandais de faire comme si nous avions un 
        // polymorphisme total qui permet de passer de Q / Q -> Q à N / N -> N de façon 
        // transparente, chose que le C++ ne permet pas
    };
    void f(Rationel const& lhs, Rationel const& rhs) {
        Rationel d = lhs / rhs;
        assert(d * rhs == lhs);
    }
    ...
    f(Rationel(1,0), Rationel(2,0));
    f(Entier(1), Entier(2)); // <-- assert failure ici
    d- Tu as proposé un fix rapide pour faire marcher entre entiers et rationnels, sauf que tu négliges tous les autres types de nombres comme les complexes, les réels, les quaternions, etc.

    e- Au contraire on garde toute l'info quand on manipule des templates. Avec le polymorphisme d'inclusion dynamique, l'info est perdue. Ou plutôt on n'a pas de moyen simple (sans enveloppe-lettre) d'exécuter les bonnes opérations.
    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...

Discussions similaires

  1. Appel d'une méthode virtuelles
    Par BIPBIP59 dans le forum C++Builder
    Réponses: 4
    Dernier message: 24/03/2006, 14h00
  2. Méthodes virtuelle et implémentation
    Par slate dans le forum C++
    Réponses: 2
    Dernier message: 16/02/2006, 17h16
  3. méthodes virtuelles
    Par ep31 dans le forum C++
    Réponses: 2
    Dernier message: 09/11/2005, 17h21
  4. Comment l'appel à une méthode virtuelle....
    Par Blobette dans le forum C++
    Réponses: 7
    Dernier message: 07/12/2004, 13h55
  5. [C#] Méthode virtuelle
    Par jacma dans le forum Windows Forms
    Réponses: 4
    Dernier message: 07/11/2004, 08h18

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