textual sintaxis semantica relacion linguistica lexico lexica entre ejemplos definicion c++ methods const

c++ - sintaxis - ¿Cuál es la semántica de una función de miembro constante?



semantica y sintaxis definicion (9)

Además del hecho de que la función miembro puede modificar datos globales, es posible que la función miembro modifique los miembros mutables explícitamente declarados del objeto en cuestión.

Entiendo que la función no permite cambiar el estado del objeto, pero pensé que leí en alguna parte que el compilador podía suponer que si la función se llamaba con los mismos argumentos, devolvería el mismo valor y, por lo tanto, podría reutilizarse un valor en caché si estaba disponible. p.ej

class object { int get_value(int n) const { ... } ... object x; int a = x.get_value(1); ... int b = x.get_value(1);

entonces el compilador podría optimizar la segunda llamada y usar el valor en un registro o simplemente hacer b = a;

¿Es esto cierto?


Corey está en lo cierto, pero tenga en cuenta que cualquier variable miembro que esté marcada como mutable se puede modificar en las funciones miembro integradas.

También significa que estas funciones se pueden llamar desde otras funciones const, o a través de otras referencias const.

Editar: Maldición, fue vencido por 9 segundos ... ¡¡¡9 !!! :)


En este contexto, una función de miembro const significa que this se trata como un puntero de const . En términos prácticos, significa que no tiene permitido modificar el estado de this dentro de una función de miembro const .

Para las funciones sin efectos secundarios (es decir, lo que intenta lograr), GCC tiene un "atributo de función" llamado pure (lo usa diciendo __attribute__((pure)) ): http: //gcc.gnu. org / onlinedocs / gcc / Function-Attributes.html


La palabra clave mutable en las variables miembro permite que las funciones const alteren el estado del objeto en cuestión.

Y no, no almacena datos en caché (al menos no todas las llamadas) ya que el siguiente código es una función const válida que cambia con el tiempo:

int something() const { return m_pSomeObject->NextValue(); }

Tenga en cuenta que el puntero puede ser const, aunque el objeto apuntado no es const, por lo tanto, la llamada a NextValue en SomeObject puede o no alterar su propio estado interno. Esto hace que la función algo devuelva valores diferentes cada vez que se llama.

Sin embargo, no puedo responder cómo funciona el compilador con los métodos const. He oído que puede optimizar ciertas cosas, aunque tendré que buscarlo para estar seguro.


La palabra clave const en una función miembro marca este parámetro como constante. La función aún puede silenciar datos globales (por lo que no se pueden almacenar en caché), pero no datos de objetos (lo que permite realizar llamadas a objetos const).


Lo dudo, la función todavía podría llamar a una función global que altera el estado del mundo y no viola la const.


Los métodos const también pueden modificar locals estáticos. Por ejemplo, lo siguiente es perfectamente legal (y las llamadas repetidas a bar () devolverán valores crecientes, no un 0 en caché):

class Foo { public: int bar() const { static int x = 0; return x++; } };


No.

Un método const es un método que no cambia el estado del objeto (es decir, sus campos), pero no se puede asumir que dada la misma entrada, se determina el valor de retorno de un método const. En otras palabras, const keyword NO implica que la función sea uno a uno. Por ejemplo, un método que devuelve la hora actual es un método const pero su valor de retorno cambia entre llamadas.


const es sobre semántica de programa y no sobre detalles de implementación. Debe marcar una función de const cuando no cambie el estado visible del objeto, y debe ser invocable en un objeto que sea const . Dentro de una función miembro miembro en una clase X , el tipo de this es X const * : puntero a objeto X constante. Por lo tanto, todas las variables miembro están efectivamente const dentro de esa función miembro (excepto las variables). Si tiene un objeto const , solo puede llamar a las funciones miembro de const .

Puede usar mutable para indicar que una variable miembro puede cambiar incluso dentro de una función miembro miembro. 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 miembro integradas) 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 por puntero en lugar de directamente (incluidos los punteros inteligentes como std::auto_ptr o boost::shared_ptr ), el puntero se convierte en const en una función de miembro const , pero no en los datos apuntados, por lo que puede modificar el 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 solo se llame una vez.

La próxima versión del Estándar C ++ (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).