Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Discussion : Peut-on créer une méthode virtuelle const ?

Le , par NiamorH

0PARTAGES

1  0 
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 ?

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de JolyLoic
Rédacteur/Modérateur https://www.developpez.com
Le 02/11/2008 à 2:32
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.
0  0 
Avatar de Alp
Expert éminent sénior https://www.developpez.com
Le 02/11/2008 à 2:49
Exemple "bête" :
Code : Sélectionner tout
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é.
0  0 
Avatar de NiamorH
Membre éprouvé https://www.developpez.com
Le 02/11/2008 à 10:26
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.
0  0 
Avatar de Alp
Expert éminent sénior https://www.developpez.com
Le 02/11/2008 à 11:30
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
0  0 
Avatar de JolyLoic
Rédacteur/Modérateur https://www.developpez.com
Le 02/11/2008 à 11:55
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.
0  0 
Avatar de Médinoc
Expert éminent sénior https://www.developpez.com
Le 02/11/2008 à 12:13
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...
0  0 
Avatar de koala01
Expert éminent sénior https://www.developpez.com
Le 02/11/2008 à 14:01
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.
0  0 
Avatar de NiamorH
Membre éprouvé https://www.developpez.com
Le 02/11/2008 à 14:54
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.
0  0 
Avatar de Médinoc
Expert éminent sénior https://www.developpez.com
Le 02/11/2008 à 14:56
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...
0  0 
Avatar de koala01
Expert éminent sénior https://www.developpez.com
Le 02/11/2008 à 15:19
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
0  0