data - function c++
C++ "const" explicación de palabras clave (8)
Al leer tutoriales y código escrito en C ++, a menudo me tropiezo con la palabra clave const
.
Veo que se usa como la siguiente:
const int x = 5;
Sé que esto significa que x
es una variable constante y probablemente se almacena en la memoria de solo lectura.
Pero que son
void myfunc( const char x );
y
int myfunc( ) const;
?
Antes de un identificador de variable, const
indica que la variable se puede inicializar y, posteriormente, no modificar.
Después de un nombre de método de clase, const
indica que el método no modificará el estado observable de la clase. La palabra clave mutable
permite modificar los datos internos.
Antes de un puntero o una variable de referencia, const
indica que el identificador no se utilizará para modificar los datos a los que se hace referencia, aunque se puede cambiar por otros medios.
const int *pInt = &x;
Const también se puede utilizar para indicar que el puntero en sí no se puede modificar:
int * const pInt = &x;
El calificador const
significa que una variable / puntero definido como const
no puede ser cambiado por su programa y recibirá su valor ya sea por una inicialización explícita o por un medio dependiente del hardware.
Un puntero que se define como const
en las declaraciones de parámetros, el código de función no modificará lo que apunta. Básicamente, puede usar el puntero y funciona prácticamente como "solo lectura".
Por ejemplo:-
void foo(const char *x)
{
while(*x)
{
if(*x=='' '') cout << ''-''; //printing - when a space is encountered
else cout << *x;
x++;
}
}
La función anterior está bien y no mostrará ningún error. Pero si foo tuviera alguna cosa que pudiera cambiar la cadena pasada. Digamos una función que reemplaza espacios con $. No imprime $ pero cambiándolo a $. Algo como esto:-
void foo(const char *x)
{
while(*x)
{
if(*x=='' '') *x = ''$''; //printing - when a space is encountered
else cout << *x;
x++;
}
}
entonces no se compilaría, es decir, un error de asignación a una ubicación de memoria de solo lectura.
El primer ejemplo de función es más o menos sin sentido. Más interesante sería:
void myfunc( const char *x );
Esto le dice al compilador que el contenido de *x
no será modificado. Es decir, dentro de myfunc()
no puedes hacer algo como:
strcpy(x, "foo");
El segundo ejemplo, en una función miembro de C ++, significa que la llamada no cambiará el contenido del objeto.
Así dado:
class {
int x;
void myfunc() const;
}
someobj.myfunc()
no tiene permitido modificar nada como:
x = 3;
Esta:
void myfunc( const char x );
significa que no puedes cambiar x
dentro de la función, es decir, esto es ilegal:
void myfunc( const char x ) {
x = ...;
}
mientras:
int myfunc() const;
solo tiene sentido si myfunc () es un método dentro de una clase; básicamente significa que el método no puede modificar la instancia de la clase (es decir, el estado de la instancia antes y después de llamar a instance.myfunc () será el mismo).
He encontrado una muy buena explicación en: http://duramecho.com/ComputerInformation/WhyHowCppConst.html
Básicamente, toda confusión se encuentra en los diferentes casos de uso de la palabra clave const
. Dependiendo de dónde se coloque, debe indicar que algo debe ser inmutable o que algo no debe poder cambiar algo. ''algo'' puede ser una variable o un puntero o una función / método, que no desea que pueda cambiar el valor de las variables pasadas a las funciones o variables miembro del objeto.
La diferencia entre los dos es que el primero tiene el tipo void(char)
y el segundo tiene el tipo int()const
.
Una función que tiene un tipo de este tipo con const
al final solo puede ser una función miembro de una clase, y significa que la función miembro no cambia el valor de la clase (a lo que se refiere this
) como se ve desde fuera de la clase. El compilador verificará eso hasta cierto punto, y cualquier escritura directa a un miembro de la clase en una función de miembro de const produce un error de tiempo de compilación, y la función solo puede llamar directamente a las funciones de miembro de const en sí misma (existen directivas especiales para que pueda decirle al el compilador que un miembro escribe no cambiará el valor de la clase como se ve desde afuera. Esto se hace con la palabra clave mutable
).
En las funciones que presentaste, una tenía un parámetro de tipo char const
. Tal parámetro no puede ser cambiado dentro de su función. Sin embargo, no tiene ningún efecto en el tipo de la función, y no tiene ningún efecto para las personas que llaman a la función.
void myfunc(const char x)
es muy similar a const int x = 5
en su ejemplo: declara una constante disponible localmente dentro de la función myfunc
. Como es una constante, su valor no puede ser cambiado.
int myfunc() const
es una función miembro de una clase. La const
indica que la función no cambiaría la instancia de la clase en la que se ejecuta la función. Entonces, dentro de la función, no puedes hacer algo como this->foo = 7
o llamar a otra función que no sea constante.
void myfunc(const char x);
Esto significa que el parámetro x
es un carácter cuyo valor no se puede cambiar dentro de la función. Por ejemplo:
void myfunc(const char x)
{
char y = x; // OK
x = y; // failure - x is `const`
}
Para el último:
int myfunc() const;
Esto es ilegal a menos que esté dentro de una declaración de clase (las funciones de miembro const
impiden la modificación de cualquier miembro de la clase) no se pueden usar las funciones de miembro no const
. En este caso la definición sería algo como:
int myclass::myfunc() const
{
// do stuff that leaves members unchanged
}
Si tiene miembros de clase específicos que necesitan ser modificables en funciones de miembro const
, puede declararlos mutable
. Un ejemplo sería un miembro lock_guard
que hace que las funciones miembro de const
y non- const
la clase sean seguras para subprocesos, pero deben cambiar durante su propia operación interna.