513 votes

Le mot clé 'mutable' a-t-il un autre but que de permettre à la variable d'être modifiée par une fonction const?

Il y a un moment je suis tombé sur un code qui a marqué une variable membre d'une classe avec l' mutable mot-clé. Aussi loin que je peux voir, il vous permet simplement de modifier une variable dans une const méthode:

class Foo  
{  
private:  
    mutable bool done_;  
public:  
    void doSomething() const { ...; done_ = true; }  
};

Est-ce la seule utilisation de ce mot-clé ou est-il plus à lui que rencontre l'œil? Depuis, j'ai utilisé cette technique dans une classe, marquant un boost::mutex comme mutable permettant const fonctions pour le verrouiller pour fil raisons de sécurité, mais, pour être honnête, il se sent comme un peu un hack.

342voto

KeithB Points 9459

Elle permet la différenciation des bits const et logique const. Const logique est lorsqu’un objet ne change pas d’une manière qui soit visible à travers l’interface publique, comme dans votre exemple de verrouillage. Un autre exemple serait une classe qui calcule une valeur de la première fois, il est demandé et met en cache le résultat.

Depuis le c ++11 `` peut être utilisé sur un lambda pour indiquer que les choses saisies par valeur sont modifiables (ils ne sont pas par défaut) :

134voto

Dan L Points 483

L' mutable de mots clés est une façon de percer l' const voile de vous draper sur vos objets. Si vous avez un const référence ou un pointeur vers un objet, vous ne pouvez pas modifier l'objet en aucune façon , sauf quand et comment elle est marquée mutable.

Avec votre const de référence ou un pointeur vous sont limitées à:

  • accès en lecture seule pour tout visible par les membres de données
  • l'autorisation d'appeler que des méthodes qui sont marqués comme const.

L' mutable d'exception fait de sorte que vous pouvez maintenant écrire ou de données ensemble de membres qui sont marqués mutable. C'est la seule visible de l'extérieur de la différence.

En interne, ces const méthodes qui sont visibles, vous pouvez aussi écrire des données sur des membres qui sont marqués mutable. Essentiellement la const voile est percé de manière exhaustive. Il est complètement à l'API concepteur de s'assurer que mutable ne pas détruire l' const concept et est utilisé uniquement utile dans des cas particuliers. L' mutable mot-clé aide parce qu'il marque clairement des données des membres qui sont soumis à ces cas particuliers.

Dans la pratique, vous pouvez utiliser const obsessionnelle tout au long de votre base de code (vous voulez "infecter" de votre base de code avec l' const "maladie"). Dans ce monde, les pointeurs et les références sont const à de très rares exceptions, produisant un code qui est plus facile à comprendre et à comprendre. Pour une intéressante digression rechercher "référentiel de la transparence".

Sans l' mutable mot-clé, vous finirez par être forcé d'utiliser const_cast pour gérer les diverses utiles des cas particuliers, il permet la mise en cache, ref comptage, des données de débogage, etc.). Malheureusement, const_cast est significativement plus destructeur qu' mutable , parce qu'il oblige l'API client pour détruire l' const protection des objets (s)qu'il utilise. En outre, il provoque généralisée const destruction: const_casting const pointeur ou d'une référence permet libre à écrire et l'appel de méthode d'accès visible des membres. En revanche mutable nécessite l'API designer à exercer un contrôle de précision sur l' const des exceptions, et généralement ces exceptions sont cachés dans const méthodes d'exploitation sur les données privées.

(N. B. je me réfère à des données et de la méthode de la visibilité à quelques reprises. Je parle des membres marqués comme public vs privé ou protégé, ce qui est un type totalement différent de la protection des objets discutés ici.)

75voto

Frank Szczerba Points 2767

L’utilisation avec boost::mutex est exactement ce qui est destiné ce mot-clé. Une autre utilisation est résultat interne de mise en cache à l’ADSL.

Fondamentalement, « mutables » s’applique à n’importe quel attribut de classe qui n’affecte pas l’état visible de l’extérieur de l’objet.

Dans l’exemple de code dans votre question, final pourrait être inapproprié si la valeur de done_ sur l’état externe, cela dépend de ce qui est dans le... ; partie.

35voto

John Millikin Points 86775

Mutable est pour marquage spécifique en tant qu'attribut modifiable à partir de l'intérieur d' const méthodes. C'est son seul but. Réfléchissez bien avant de l'utiliser, parce que votre code sera probablement plus propre et plus lisible si vous modifiez la conception plutôt que d'utiliser mutable.

http://www.highprogrammer.com/alan/rants/mutable.html

Donc, si la folie n'est pas ce que mutable, c'est pour quoi? Voici la subtile: mutable est pour l' cas où un objet est logiquement constante, mais dans la pratique, les besoins de changement. Ces cas sont rares et loin entre les deux, mais ils existent.

Les exemples de l'auteur donne incluent la mise en cache et temporaire de débogage variables.

31voto

Adam Rosenfield Points 176408

Il est utile dans les situations où vous avez caché l'état interne comme un cache. Par exemple:

la classe HashTable
{
...
public:
 recherche par chaîne de caractères(string key) const
{
 if(key == lastKey)
 retour lastValue;

 string valeur = lookupInternal(clé);

 lastKey = key;
 lastValue = valeur;

 valeur de retour;
}

privé:
 mutable chaîne lastKey, lastValue;
};

Et puis vous pouvez avoir un const HashTable objet toujours utiliser ses lookup() méthode, qui modifie le cache interne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X