en tu ejemplo, cuando tu haces:
Estás haciendo una copia. El nuevo
int tendrá una copia del valor retornado por
funcion y es por eso que puedes modificar alegremente la variable
a.
En el ejemplo que propones no es demasiado útil el uso de
const. Como no has especificado lenguaje voy a asumir que estamos hablando de C++.
Una de las grandes utilidades de
const es indicar que un argumento no va a ser modificado:
Código C++:
Ver originalvoid PrintValues(const std::string& cadena);
Viendo esta firma lo que entendemos es que esa función no va a modificar la cadena que le pasemos. Simplemente va a leer información de la misma.
Por otro lado, este diseño evita errores tontos de programación, ya que si intentamos hacer una modificación en la variable el compilador nos mostrará el error:
Código C++:
Ver originalvoid PrintValues(const std::string& cadena)
{
cadena = "test"; // Error de compilación
std::cout << cadena;
}
Eso sí, como hemos visto al principio, que un elemento sea
const no quiere decir que no se puedan hacer copias
no-const del mismo. Al fin y al cabo, al hacer una copia estamos creando un elemento nuevo a partir de otro ya existente:
Código C++:
Ver originalvoid PrintValues(const std::string& cadena)
{
std::string copia = cadena; // Copia no es const
copia = "test"; // ok
std::cout << cadena;
}
Otra utilidad de const es que permite utilizar variables como si fuesen valores fijos:
Código C++:
Ver originalint variable = 5;
const int constante = 5;
std::array<int,variable> array1; // Error -> no se pueden usar variables al definir un template
std::array<int,constante> array2; // ok
Pero... las constantes pueden ser modificadas...
En programación puedes hacer prácticamente todo lo que quieras por peligroso que parezca. Y el mundo C/C++ es un campo de pruebas perfecto para poner todo patas arriba. Un ejemplo de ello es forzar conversiones:
Código C++:
Ver originalint variable = -5;
int* ptr = &variable;
unsigned int* uptr = (unsigned int*)ptr;
std::cout << *uptr;
Entre las conversiones que se pueden realizar están aquellas que permiten eliminar el atributo
const a un objeto:
Código C++:
Ver originalvoid PrintValues(const std::string& cadena)
{
// Sintaxis propia de C++
std::const_cast<std::string&>(cadena) = "test";
// Sintaxis heredada de C
((std::string*)&cadena) = "test";
std::cout << cadena;
}
Entonces... ¿Qué sentido tiene usar
const si puedo eliminar la protección a discrección?
En primer lugar hay que tener mucho cuidado al eliminar el atributo
const a un objeto. Los objetos que "nacen"
const pueden ser almacenados en una zona de memoria de solo lectura, por lo que modificar uno de estos objetos puede provocar un resultado indeterminado.
En segundo lugar, no resulta demasiado coherente, salvo contadísimas excepciones, saltarse la protección ya que complica la comprensión del código (si alguien ve que algo es constante espera que dicho elemento se comporte como tal). Bastante compleja puede llegar a ser la programación como para que andemos plantando bombas en nuestro propio camino.
Hay más material del que hablar sobre
const, como comentar el uso del atributo
mutable, pero ya son temas más técnicos que no conviene tener en cuenta en nivel principiante.
Un saludo.