2010-09-30 17 views

Respuesta

0

Scott Meyers, Effective C++, punto 3:

Uso const siempre que sea posible

tiene una excelente discusión (con ejemplos) sobre este tema. ¡Es difícil escribir mejor que Scott!

Tenga en cuenta también que la constness física también se conoce como constness bitwise.

17

Necesita mutable cuando hay campos en un objeto que pueden considerarse "internos", es decir, cualquier usuario externo de la clase no puede determinar el valor de estos campos. La clase puede necesitar escribir en estos campos aunque la instancia se considere constante, es decir, no cambie.

Considere un disco duro; su caché es un ejemplo de tal estado. El caché es escrito cuando los datos son , lea del disco actual.

Esto no se puede expresar limpiamente en C++ sin hacer los miembros correspondientes mutable, para permitir su modificación incluso en los métodos marcados const. Como se señala en un comentario, siempre puede alcanzar el martillo y usar un const_cast<> para eliminar el const -ness, pero eso es por supuesto hacer trampa. :)

+3

Otro ejemplo similar sería un mutex en un objeto compartido por diferentes subprocesos. Una operación de lectura no modifica el objeto, pero el mutex debe ser adquirido y liberado en el proceso. El objeto mutex miembro cambia claramente durante la operación, incluso si el resultado de la operación no cambia el objeto per se. Una operación consiste en un objeto si el estado percibido permanece sin modificar, incluso si los elementos internos cambian. –

+0

¿Puedes darme un pequeño ejemplo (código) que muestra qué cosas puedo hacer con mutable y no puedo con const, que también muestra la diferencia entre lógica y constidad física? Encontré algunas explicaciones en google pero no puedo encontrar buenas ejemplo, con caché un poco difícil de entender – rookie

+0

_Esto no es posible expresar en C++ sin hacer los miembros correspondientes 'mutable'_. Esa afirmación es incorrecta, ** puede ** lograrse (y lo ha hecho en el pasado) eliminando la constidad mediante el lanzamiento del objeto o el miembro. La palabra clave 'mutable' entró después, cuando la idea de constness lógica se realizó porque los programadores estaban eliminando la constness de los objetos manualmente para obtener este efecto, por lo que es más fácil de mantener y ejecutable. Ver [aquí] (http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_025.html). – Adrian

31

Constness "física" proviene de declarar un objeto const, y podría, en principio, ser impuesta al colocar el objeto en la memoria de solo lectura, por lo que no puede cambiar. Intentar cambiarlo causará un comportamiento indefinido; podría cambiar, o no, o podría desencadenar un error de protección, o podría derretir el chip de memoria.

Constness "lógica" viene de declarar una referencia o puntero const, y es impuesta por el compilador. El objeto en sí mismo puede o no ser "físicamente" const, pero la referencia no puede usarse para modificarlo sin un molde. Si el objeto no es "físicamente" const, entonces C++ le permite modificarlo, usando const_cast para eludir la protección.

Un miembro de clase mutable se puede modificar incluso si el objeto de clase en sí (o la referencia o el puntero utilizado para acceder a él) es const. Ejemplos de buenos usos de esto son un mutex que debe bloquearse durante una operación de lectura y un caché para almacenar el resultado de una costosa operación de lectura. En ambos casos, la operación en sí debería ser una función const (ya que no afecta el estado visible del objeto), pero necesita modificar el mutex o el caché, por lo que deben ser mutable. También se puede abusar para hacer que el objeto cambie visiblemente cuando lógicamente no debería, así que úselo con cuidado; solo declare los miembros mutable si no forman parte del estado visible externamente.

+1

+1, muy buena explicación. – Dan

+1

Eso se lee muy bien :-), pero está muy mal :-(. "Constness" física "viene de declarar un objeto const" - 'const' no garantiza su" constness física ": los miembros pueden seguir siendo' mutable' y cambiado en tiempo de ejecución. Debido a que esto está permitido, el compilador/enlazador, etc., no colocará dichos objetos en la memoria de solo lectura de manera predeterminada, incluso si son 'const estáticos'. Si son forzados allí a través de algunos no - Banderas estándar de compilador/enlazador/cargador, entonces el programador debe evitar manualmente los miembros 'mutables'. La distinción que dibuja entre objetos y puntero/referencias es realmente irrelevante. –

+0

@TonyDelroy - Respondí la respuesta de Mike que implicaba" colocar el objeto en lectura ". solo memoria "como una afirmación retórica (y retóricamente efectiva) para hacer una observación sobre la diferencia entre el' const' físico y el 'const lógico ', no como una afirmación de que los compiladores realmente lo harán, ni dijo que los compiladores * lo harán esto. Además, no estoy de acuerdo en que su disti nction entre punteros y referencias es irrelevante. La respuesta es conceptualmente sólida y correcta. TonyDelroy es, en mi opinión, incorrecto cuando afirma que la respuesta es "muy incorrecta". –

Cuestiones relacionadas