OVH Cloud OVH Cloud

Bon usage du qualificateur "const" pour fonctions membres

22 réponses
Avatar
bylybob
Bonjour a tous, je suis pris d'un doute sur le bon usage du
qualificateur "const" pour les fonctions membres dans certains cas
particuliers: objects transitoires dont le but est simplement de
calculer des informations sur un autre object.

Prenons l'exemple de calcul scientifique, typiquement il y a un
"maillage" (par exemple un ensemble de triangles munis de proprietes
geometriques et mecaniques) et un "calculateur" (par exemple elements
finis munis de parametres de calculs). Le "calculateur" calcule (!) et
stocke les resultats sur la grille.

Le "calculateur" a naturellement une fonction "bool calcule();" qui ne
change pas les parametres de calcul mais va rajouter certainnes
proprietes (le resultat du calcul) sur le maillage.

Alors "bool calcule();" ou "bool calcule() const;"?

Merci,

bylybob


class calculateur {
public:
calculateur(maillage* m, <parametre de calcul...>);

bool calcule() const { // Const ou pas const?
//- Calcule des trucs...
m->stocke(resultat);
//...
}

private:
struct Impl; // Details
//...
};

2 réponses

1 2 3
Avatar
Fabien LE LEZ
Avatar
James Kanze
On Jun 16, 9:23 pm, "Patrick 'Zener' Brunet"
wrote:
"James Kanze" a écrit dans le message
de news:




> On Jun 15, 8:59 pm, "Patrick 'Zener' Brunet"
> wrote:
> > Mais comme tu le précises:
> > [...]
> > mais pas (dans une classe):



> > int * mutable mpi; // passerait comme attendu
> > int mutable * pmi; // là c'est râté...
> Au contraire, c'est le premier qui ne passe pas.
> Le « mutable » peut prendre les mêmes positions que
> « static » ou « extern » dans une declaration, c-à-d
> n'importe où dans la « declaration-specifier-seq »,
> mais seulement dans elle.



Alors j'ai bien fait d'aller au fond des choses, parce que
moi j'en ai un qui passe depuis longtemps, au moins sur
MS Visual C++ v.6:



template< class T>
class CmHolderByValue
{
private:
T mutable _xValue;
public:
...
};



« T mutable » marche. C'est « T * mutable » qui pose de
problèmes.

Que je valide sans problème avec T = int * ou void *.



Ce n'est pas le type qui pose de problème, c'est la façon de
l'écrire. Le syntaxe ne permet pas de « mutable » dans un
déclarateur. Et ne permet pas de « * » ailleurs. Rappel-toi de
la syntaxe d'une déclaration: c'est une decl-specifier-seq,
suivi d'une init-declarator-list. (En fait, les deux sont
facultatifs ; on peut avoir des declarations sans
decl-specifier-seq, ou sans init-declarator-list. Encore que
depuis qu'on a supprimé l'int implicit, je ne vois pas trop
comment se passer du decl-specifier-seq.) Le mutable doit se
trouver dans le decl-specifier-seq, avec le nom du type. Le '*'
qui dit que c'est un pointeur fait partie de la
init-declarator-list. Mais un nom d'un type peut bien spécifier
un pointeur, ou n'importe quel autre type.

Et cette classe est très largement utilisée, avec succès. De
plus je force le test par instanciation de toutes les méthodes
de chacun de mes templates avec tous les types d'arguments, en
instance const et non const. Aucune erreur.



A moins bien sûr que l'instanciation du template ci-dessus
remette les choses en ordre: le compilo réordonnerait en
"mutable T" avant d'instancier ?



Pas besoin. Le nom du type est T. Qu'il soit un pointeur, ou
n'importe quoi d'autre, c'est le nom du type, qui se trouve dans
le decl-spécifier-seq.

C'est vrai que je n'ai pas d'exemple de pointeur mutable dans
mes classes ordinaires.



Ce n'est pas la différence template ou non qui joue. Si tu
écris :
typedef int * IntPtr ;
tu peux mettre le « mutable » après l'IntPtr aussi. En
revanche, même dans un template :
template< typename T >
class Toto
{
T * mutable mPtr ;
} ;

est illégal.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
1 2 3