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 :

[POO] Méthodes virtuelles const ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut [POO] Méthodes virtuelles const ?
    Voila, il est plus de minuit et demi maintenant et je me pose une question existencielle :

    Les méthodes d'interface et autres méthodes virtuelles "ont-elles le droit" d'être déclarées const?

    A moins de cas particuliers, mais je n'en vois pas, même en cherchant, c'est à l'implémentation de décider si, oui ou non, la méthode redéfinie va être amenée à modifier l'objet.

    Quel est votre avis la-dessus ?

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Oui, elles en ont le droit. Être const fait partie du contrat, et c'est la classe de base qui fixe le contrat. C'est elle qui dit qu'une fonction aura N paramètres de tels ou tels types, c'est aussi elle qui dit si on pourra l'appeler sur un objet constant.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Exemple "bête" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class GraphicObject
    {
      public :
        virtual void Draw() const = 0;
    };
     
    class Ball : public GraphicObject
    {
      public : 
        void Draw() const { /* on affiche la balle */ }
    }
    La méthode Draw ne modifiant pas l'instance, on peut la "const-qualifier", et ainsi elle pourra être appelée sur des objets constants, tout en préservant le polymorphisme désiré.

  4. #4
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Bonjour,

    si j'écris ton exemple tel quel, Alp, j'ai l'erreur "cannot instanciate abstract class" car la méthode Draw de Ball n'est justement pas const alors que celle GraphicObject est déclarée comme l'étant.

    Et c'est bien là le fond du problème. Je suis tout à fait d'accord avec vous pour dire que décider de rendre une méthode virtuelle const établi un contrat qui doit suivre une logique et que cela doit être fait lors du design de la classe abstraite de base.
    Seulement je trouve pleins de cas où cela pose problème.

    Si je reprends l'exemple de l'objet graphique et sa méthode Draw() : l'objet est dans un certain état (position, couleur etc.) et on lui demande de s'afficher en l'état, à priori sans le modifier, de façon à ce que si l'on appelle à nouveau cette méthode juste derrière, le même affichage devrait nous être donné. Donc notre méthode est const vis à vis de l'objet graphique.

    Alp, tu as surement raisonné ainsi et j'aurais certainement fait pareil. Mais toujours en continuant l'exemple, imaginons que j'implémente ObjetGraphique et mon implémentation nécessite beaucoups de précalculs non négligeables avant de pouvoir effectivement se dessiner. Ces calculs dépendent de l'état de l'objet et ne devraient pas avoir à être ré-éxécutés si l'état n'a pas changé depuis le dernier appel à Draw(). Et bien, à part en déclarant des variables mutable, je ne peux pas sauver mes précalculs dans Draw().

    Voilà ce qui me chiffone depuis hier.

  5. #5
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    En fait j'ai simplement oublié le const...

    Car j'étais fatigué

    Mais tu peux pas casser la qualification const, effectivement. J'édite le code ci-dessus

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    imaginons que j'implémente ObjetGraphique et mon implémentation nécessite beaucoups de précalculs non négligeables avant de pouvoir effectivement se dessiner. Ces calculs dépendent de l'état de l'objet et ne devraient pas avoir à être ré-éxécutés si l'état n'a pas changé depuis le dernier appel à Draw(). Et bien, à part en déclarant des variables mutable, je ne peux pas sauver mes précalculs dans Draw().
    Et justement, tu peux les déclarer mutable, et alors, ça marche. Je ne vois pas trop ce qui te gène dans ce cas.

    Et le mutable n'est pas là "pour faire plaisir" à la classe de base : Il est là parce que, indépendamment de toute autre chose, ton objet n'est pas sémantiquement modifié par son affichage, le fait qu'il y ait des pré-calculs mis en cache n'étant qu'un détail d'implémentation ne devant pas apparaître dans l'interface.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    Par défaut
    Pour moi, un truc qui "aide" à comprendre les variables mutables, c'est de se dire que ce ne sont pas des variables à part entière de la classe, juste des détails d'implémentation.
    Ce qui est le cas pour la plupart des utilisations de variables mutables: Comptage de références intrusif, cache, et compteurs d'appels...
    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.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Salut,

    Le role d'une méthode const est de préciser au compilateur "cette méthode ne modifie pas l'objet".

    Par le fait de modifier l'objet, il faut comprendre le fait de modifier les "propriétés intrinsèques" qui font que ta balle rouge et bleue d'un diametre de N n'est pas une balle verte et jaune d'un diamètre de 2N, et que, au moment de l'appel, sa position et son "orientation" (le fait que le rouge soit en haut à gauche et le bleu en bas à droite) se seront pas modifiée.

    Par contre, si pour t'éviter d'avoir à recalculer en permanence l'aspect à donner à ta balle, tu décide de mettre cet aspect dans un cache, tu te trouve exactement dans le cas d'utilisation d'une variable mutable: ca ne modifie absolument pas les propriétés intrinsèques de la balle, cela ne modifie que la manière dont la méthode d'affichage va représenter la balle dans la situation donné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

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Effectivement, le mot clef mutable est la solution que j'utilise. Mais ça m'a toujours géné d'y avoir recours. Dans ma tête je me suis toujours dis "tu as dû mal penser quelque chose pour en arriver à devoir t'en servir."

    Peut être que je me fais du mauvais sang pour rien après tout.

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    Par défaut
    Je me disais la même chose au début, c'est d'ailleurs pourquoi j'ai restreint mon utilisation de mutable au comptage de références intrusif et aux caches...
    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.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Effectivement, tu te fais beaucoup de mauvais sang pour rien...

    Bien sur, comme beaucoup de choses en programmation, il faut toujours se poser la question de savoir si oui ou non il est opportun de déclarer un membre mutable...

    Bien sur, l'abus de déclaration de membres mutables est au minimum le signe d'une réflexion sans doute erronée.

    Mais, une fois que tu a clairement défini qu'un membre agit comme un cache, comme une machine à état qui peut devenir invalide à n'importe quel moment (y compris au sein de méthodes constantes), et que la modification de ce membre ne modifie en rien les "propriétés intrinsèques" de l'objet en cours, tu es clairement dans le cadre dans lequel il est "opportun" de déclarer le membre mutable
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 14
    Dernier message: 21/11/2008, 16h29
  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