const
es sobre la semántica del programa y no sobre los detalles de implementación. Debe marcar una función de miembro const
cuando no cambie el estado visible del objeto, y debe ser invocable en un objeto que sea él mismo const
. Dentro de una función de miembro const
en una clase X
, el tipo de this
es X const *
: apunta al objeto constante X
. Por lo tanto, todas las variables miembro son efectivamente const
dentro de esa función miembro (excepto mutable
). Si tiene un objeto const
, solo puede llamar al const
funciones miembro.
Puede usar mutable
para indicar que una variable miembro puede cambiar incluso dentro de una función de miembro const
. Esto se usa generalmente para identificar las variables utilizadas para los resultados del almacenamiento en caché, o para las variables que no afectan el estado real observable, como mutexes (aún necesita bloquear el mutex en las funciones de miembro const
) o usar contadores.
class X
{
int data;
mutable boost::mutex m;
public:
void set_data(int i)
{
boost::lock_guard<boost::mutex> lk(m);
data=i;
}
int get_data() const // we want to be able to get the data on a const object
{
boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
return data;
}
};
Si mantiene los datos de puntero en lugar de hacerlo directamente (incluyendo punteros inteligentes como std::auto_ptr
o boost::shared_ptr
), el puntero se convierte en const
en una función const
miembro, pero no al cual apunta a los datos, por lo que puede modificar los datos apuntados.
En cuanto al almacenamiento en caché: en general, el compilador no puede hacer esto porque el estado puede cambiar entre llamadas (especialmente en mi ejemplo de subprocesos múltiples con el mutex). Sin embargo, si la definición está en línea, el compilador puede insertar el código en la función de llamada y optimizar lo que puede ver allí. Esto podría ocasionar que la función efectivamente solo se llame una vez.
La próxima versión del C++ Standard (C++0x) tendrá una nueva palabra clave constexpr
. Las funciones etiquetadas constexpr
devuelven un valor constante, por lo que los resultados pueden almacenarse en caché. Hay límites sobre lo que puede hacer en dicha función (para que el compilador pueda verificar este hecho).
¡Ah! constexpr era probablemente lo que estaba pensando! Gracias. – Ferruccio
Usted hizo mi día, señor. No sabía todo lo que siempre necesitaba era el 'mutable'. Muchas gracias. – lucastamoios