2010-09-30 2 views

Répondre

0

Scott Meyers, Effective C++, article 3:

utilisation const chaque fois que possible

a une excellente discussion (avec des exemples) sur ce sujet. C'est difficile d'écrire mieux que Scott!

Notez également que la constance physique est également connue sous le nom de constance au niveau du bit.

17

Vous avez besoin de mutable lorsqu'il existe des champs dans un objet pouvant être considérés comme "internes", c'est-à-dire qu'aucun utilisateur externe de la classe ne peut déterminer la valeur de ces champs. La classe peut avoir besoin d'écrire dans ces champs même si l'instance est considérée comme constante, c'est-à-dire qu'elle ne change pas.

Considérons un disque dur; son cache est un exemple d'un tel état. Le cache est écrit lorsque les données sont lire à partir du disque réel.

Il n'est pas possible d'exprimer proprement en C++ sans faire les membres correspondants mutable, pour permettre de les modifier même dans les méthodes marquées const. Comme indiqué dans un commentaire, vous pouvez toujours atteindre pour le marteau et utiliser un const_cast<> pour supprimer le const -ness, mais c'est bien sûr la tricherie. :)

+3

Un autre exemple serait un mutex dans un objet partagé par différents threads. Une opération de lecture ne modifie pas l'objet, mais le mutex doit être acquis et libéré dans le processus. L'objet membre mutex change clairement pendant l'opération, même si le résultat de l'opération ne change pas l'objet lui-même. Une opération est const sur un objet si l'état perçu reste inchangé, même si les éléments internes changent. –

+0

pouvez-vous s'il vous plaît me donner un petit exemple (code) qui montre ce que je peux faire avec mutable et ne peut pas avec const, qui montre aussi la différence entre logique et const'ness physique je trouve quelques explications dans google mais ne trouve pas bien par exemple, avec cache un peu difficile à comprendre – rookie

+0

_Ceci n'est pas possible d'exprimer en C++ sans rendre les membres correspondants 'mutable'_. Cette affirmation est incorrecte, mais elle peut être accomplie (et l'a été dans le passé) en enlevant la constance en jetant l'objet ou le membre. Le mot-clé 'mutable' est venu après, quand l'idée de constness logique a été réalisée parce que les programmeurs enlevaient manuellement la constance des objets pour obtenir cet effet, le rendant plus maintenable et exécutable. Voir [ici] (http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_025.html). – Adrian

31

La constance "physique" provient de la déclaration d'un objet const, et pourrait, en principe, être appliquée en plaçant l'objet en mémoire morte, de sorte qu'il ne peut pas changer. Tenter de le changer provoquera un comportement indéfini; cela pourrait changer, ou ne pas le faire, ou cela pourrait déclencher une erreur de protection, ou cela pourrait faire fondre la puce mémoire. La constance "logique" vient de la déclaration d'une référence ou d'un pointeur const et est appliquée par le compilateur. L'objet lui-même peut être ou non "physiquement" const, mais la référence ne peut pas être utilisée pour le modifier sans un cast. Si l'objet n'est pas "physiquement" const, alors C++ vous permet de le modifier, en utilisant const_cast pour contourner la protection. Un membre de classe mutable peut être modifié même si l'objet de classe lui-même (ou la référence ou le pointeur utilisé pour y accéder) est const. Des exemples de bonnes utilisations de ceci sont un mutex qui doit être verrouillé pendant une opération de lecture, et un cache pour stocker le résultat d'une opération de lecture coûteuse. Dans les deux cas, l'opération elle-même devrait être une fonction const (puisqu'elle n'affecte pas l'état visible de l'objet), mais elle doit modifier le mutex ou le cache, donc ceux-ci doivent être mutable. Il peut également être abusé pour que l'objet change visiblement quand il ne devrait pas logiquement, alors utilisez-le avec soin; ne déclarez les membres mutable que s'ils ne font pas partie de l'état externe visible.

+1

+1, très belle explication. – Dan

+1

Cela se lit très bien :-), mais c'est très faux :-(. "La constance" physique "vient de déclarer un objet const" - 'const' ne garantit pas votre" constance physique ": les membres peuvent encore être 'mutables' Étant donné que cela est autorisé, le compilateur/éditeur de liens etc. ne placera pas ces objets dans la mémoire morte par défaut, même s'ils sont 'static const'. -Standard drapeaux de compilateur/linker/loader, alors le programmeur doit éviter manuellement les membres 'mutable' La distinction que vous faites entre les objets et les pointeurs/références est en fait sans importance –

+0

@TonyDelroy - J'ai pris la réponse de Mike impliquant" placer l'objet en lecture- seulement la mémoire "comme une déclaration rhétorique (et rhétoriquement efficace) pour faire un point sur la différence entre la const et la logique, pas comme une déclaration que les compilateurs vont réellement faire cela, et il n'a pas non plus déclaré que les compilateurs En outre, je ne suis pas d'accord que ses disti La relation entre les pointeurs et les références n'est pas pertinente. La réponse est conceptuellement solide et correcte. TonyDelroy est, à mon avis, incorrect lorsqu'il dit que la réponse est «très fausse». –

Questions connexes