2011-01-14 26 views
8

Después de leer this, entiendo que declarar un método como const impide que se modifique accidentalmente las variables de miembro de la clase.Funciones de miembro constante

  • ¿Son los métodos const de uso común?
  • ¿Deberían usarse para todo que no debería modificar las variables de miembro?

Respuesta

14

Sí, const siempre se debe utilizar, cuando corresponda.

¡Le permite a su compilador verificar la lógica de su aplicación, afirmando estáticamente const-correctness gratis!

Algunas personas incluso dicen que const debe ser el predeterminado, y debe forzarse a usar mutable para lo que no es constante.

+1

Además, puede sobrecargar funciones solo en el calificador 'const' de la función. Esto permite, por ejemplo, un operador de índice que devuelve automáticamente el elemento en una forma de solo lectura * si el objeto se declara como 'const'. [* read-only aún solo se aplica en tiempo de compilación, sin embargo. 'const' no puede hacer nada en tiempo de ejecución] – Mephane

+0

+1 para const-correctness. nadie más lo mencionó –

+0

Estoy pensando en su declaración "const como el valor predeterminado, y mutable para no constante". Parece una posición extrema, pero intentaré sentir lo que pienso al respecto. –

6

Uso const extensivamente para comunicar intenciones de diseño. Si tuviera la intención de que un método fuera una consulta pura, y no una función de modificación, lo haría cumplir y comunicarlo con un 'const' en la firma.

Lo invito a que vea las ideas de Meyer sobre el tema de las funciones libres de efectos secundarios y las implicaciones que tiene sobre la habilitación de las pruebas.

1

Al agregar const a una función de miembro, se puede invocar en referencias const a un objeto, ya que garantiza que las variables de instancia no se modificarán. Las referencias de Const ocurren en varios lugares a lo largo del STL, por lo que tiene sentido marcar las funciones de miembro como const donde la función no tiene la intención de modificar el estado de un objeto.

Nota: es posible marcar ciertas variables de instancia como mutable, por lo que pueden modificarse incluso mediante funciones const. Esto es útil para implementar cachés de búsqueda, por ejemplo.

1

Declarar un método que no debe modificar las variables miembro:

  1. asegura que lo que usted piensa es lo que está pasando, es decir que no se está modificando accidentalmente una variable en alguna parte.
  2. Declara a los llamantes de la función que este método no modifica las variables miembro, eliminando la necesidad de leer el código o de la documentación que lo dice.

Así que sí, use const donde sea que tenga sentido. Sin embargo, no son tan ampliamente utilizados como me gustaría ver, probablemente porque la mayoría de los desarrolladores no ven el gran beneficio.

1

Si olvida marcar un descriptor de acceso como const, el compilador no permitirá que se llame al método en objetos const o referencias a objetos const. Así que sí, marcando accesos como constes importante.

+0

Sí, sé el dolor cuando la gente se olvida de declarar getters como const. Tenemos que trabajar con un marco aquí que ignora por completo el concepto y tiene todas las funciones miembro, incluidos getters, como no const. Ahora tenemos que pasar el puntero/referencias como no const cuando queremos acceder a dicho objeto, incluso si definitivamente solo queremos leer ... -_- – Mephane

1

Si tiene una referencia constante o un puntero (es decir, un puntero a const) de un objeto de clase, entonces SOLAMENTE puede llamar a los métodos miembro const de la clase.

Así que si alguien "olvidó" crear un método "get" const, no podría llamarlo con una referencia constante (¡Hay una solución con const_cast pero no queremos usar eso!).

Así que sí, si la clase no va a ser modificada por el método, entonces debería ser const.

Nota: hay ocasiones en las que desea modificar una variable como un "detalle de implementación", por ejemplo, carga lenta o bloquear un mutex. En tal caso, puede hacer que el método sea constante, pero haga que esa variable miembro sea "mutable".

Si está escribiendo un método virtual, debería ser const si ninguna clase derivada lo necesita para ser mutable.

1

Debe usar la palabra clave const siempre que sea posible.

Le impide cometer errores en el código.

Aumenta mucho la legibilidad del código. Todo el mundo que está leyendo la cabecera y ver palabras clave const puede entender inmediatamente que un método const no cambia el estado de un objeto y se puede utilizar sin tener miedo de que va a cambiar el objeto, por ejemplo,

4

Sólo mi testimonio. Hace

algunos años, yo todavía estaba en contra del uso de const, sólo a causa de las limitaciones en el diseño y la escritura de firmas de función más largos ... y así sucesivamente ...

Pero uno de mis líderes del proyecto siempre insistido , todo el tiempo, recordándome: "Deberías usar la función const, evita accidentes y no tiene sentido".

Y un día me enfrenté a un imposible error para encontrar. Días después de días después de días ... Una pesadilla. El diseño era demasiado grande para mí como para poder verlo en su totalidad. Busqué en vano hasta que decidí que estaba perdido.

Luego pasé dos días redefiniendo TODAS las funciones que deberían const. Lo digo en serio, dos días. (Las recompilaciones fueron largas ya que era un proyecto de 5 millones de líneas de código).

Y luego: simplemente encontré el error ... más bien el compilador encontró el error para mí: en un método getter-like, que debería haberme dado el tamaño preferido de un control gui, el código en realidad estaba computando el tamaño, pero también estaba almacenando en caché su tamaño y actualizando su tamaño ... Modificando así el objeto.

Ahora, a veces me olvido de poner const. Pero si lo noto, lo corrijo.

+0

Historia dolorosa. :) – GManNickG

Cuestiones relacionadas