Bienvenidos sean a este post, hoy veremos una particularidad para nuestras instrucciones.
Esta palabra clave tiene dos usos particulares en nuestros codigos. Si lo usamos en un codigo, permite que estas variables mantengan su valor en distintos llamados, ya sea de una misma funcion o varias. Vamos a aplicarlo en un ejemplo:
#include <iostream>
int contar()
{
static int total = 0;
total++;
return total;
}
int main()
{
for (int i=0; i < 5; i++)
{
std::cout << "Total = " << contar() << std::endl;
}
return 0;
}
Primero definiremos una funcion donde tendremos una variable llamada total y sera de tipo static. Este tipo de variables siempre deben tener un valor inicial, no es obligatorio pero si es lo mas recomendable porque el compilador puede tomar conductas extrañas. Lo siguiente sera incrementar el valor de esta variable y lo devolveremos. En el main tenemos un bucle que se repetira cinco veces. En este mostraremos un mensaje y haremos un llamado a la funcion anterior. Compilemos y veamos como trabaja:
$ ./estatico
Total = 1
Total = 2
Total = 3
Total = 4
Total = 5
$
Observen la particularidad, a pesar de que iniciamos el valor de la variable en cada llamada este no se aplica, salvo la primera vez. Esto es porque le indicamos al codigo que debe utilizar siempre la misma variable. Por esta razon podemos incrementarlo en cada llamada. Pero esta palabra tiene otro uso y es con las clases. Si nosotros lo aplicamos a una propiedad o un metodo en una clase nos permite utilizarlo sin necesidad de una instancia u objeto de la clase. Esto tambien permite que la propiedad o metodo puedan ser utilizados por otras clases. Tomemos el codigo anterior y realicemos la siguiente modificacion:
#include <iostream>
class Gato
{
public:
Gato(int edad): suEdad(edad) { cantidad++; }
~Gato() { cantidad--; }
int ObtenerEdad() { return suEdad; }
static int cantidad;
private:
int suEdad;
};
int Gato::cantidad = 0;
int main()
{
const int maxGatos = 5;
int i, j;
Gato *gatera[maxGatos];
for(i=0, j=1; i < maxGatos; i++, j++)
{
gatera[i] = new Gato(j * 7);
}
std::cout << "Total de Gatos: " << Gato::cantidad << std::endl;
std::cout << "Se quita al gato de 35 años" << std::endl;
delete gatera[4];
std::cout << "Quedan " << Gato::cantidad << " gatos\n";
for(i = 0; i < Gato::cantidad; i++)
{
std::cout << "Gato de " << gatera[i] -> ObtenerEdad();
std::cout << " años.\n";
}
return 0;
}
Primero definiremos una clase llamada Gato. En la parte publica primero definiremos el constructor y no solo iniciaremos la edad del mismo sino que incrementaremos una propiedad llamada cantidad. Lo siguiente es el destructor donde decrementaremos el valor de cantidad cada vez que eliminamos un objeto de esta clase. Despues de este tenemos un metodo para recuperar el valor de la edad del objeto y por ultimos tenemos nuestra propiedad estatica llamada cantidad. Esta la usaremos para contar la cantidad de gatos que crearemos. En la parte privada tenemos laa propiedad que almacenaremos la edad del gato. Antes de pasar al main le establecemos el valor a la propiedad estatica. Esto es asi por lo que comentamos anteriorrmente donde siempre las variables estaticas deben tener un valor inicial.
En el main primero declaramos una constante para establecer la cantidad maxima de gatos que crearemos. Luego declaramos dos variables que usaremos en el bucle. La primera sera para la cantidad de pasadas que haremos y la segunda sera para la edad. Lo siguiente es crear un array del tipo Gato y la cantidad sera definida por la constante. Lo siguiente es crear a los gatos y para ello usaremos un bucle donde usaremos las variables como comentamos anteriormente. Para ello iniciaremos a i con el valor de 0 y a j con el valor de 1. El limite lo establecemos mediante la constante y en el ultimo campo incrementaremos a las dos variables. En cada posicion del array llamado gatera almacenaremos cada objeto creado y para la edad usaremos el valor de j multiplicado por 7. La primer linea siguiente se encarga de indicar y mostrar la cantidad de gatos existentes. Mostramos un mensaje indicando que quitaremos a un gato. Y seguido al mensaje usaremos a delete para eliminar el objeto en esa posicion. Para mostrar la nueva cantidad de gatos y por ultimo mostrar los gatos restantes. Compilemos y veamos como es la salida:
$ ./estatico
Total de Gatos: 5
Se quita al gato de 35 años
Quedan 4 gatos
Gato de 7 años.
Gato de 14 años.
Gato de 21 años.
Gato de 28 años.
$
Como pueden ver se obtuvo lo comentado anteriormente. Pero con esta forma de trabajo tenemos un inconveniente. La variable estatica esta en la parte publica por lo tanto se puede incrementar por fuera del constructor. Lo cual puede desencadenar en errores debido al mal uso de esta variable/propiedad. Para solucionarlo debemos modificar el codigo anterior de la siguiente manera:
#include <iostream>
class Gato
{
public:
Gato(int edad): suEdad(edad) { cantidad++; }
~Gato() { cantidad--; }
int ObtenerEdad() { return suEdad; }
static int ObtenerCant() { return cantidad; }
private:
int suEdad;
static int cantidad;
};
int Gato::cantidad = 0;
int main()
{
const int maxGatos = 5;
int i, j;
Gato *gatera[maxGatos];
for(i=0, j=1; i < maxGatos; i++, j++)
{
gatera[i] = new Gato(j * 7);
}
std::cout << "Total de Gatos: " << Gato::ObtenerCant() << std::endl;
std::cout << "Se quita al gato de 35 años" << std::endl;
delete gatera[4];
std::cout << "Quedan " << Gato::ObtenerCant() << " gatos\n";
for(i = 0; i < Gato::ObtenerCant(); i++)
{
std::cout << "Gato de " << gatera[i] -> ObtenerEdad();
std::cout << " años.\n";
}
return 0;
}
El codigo es muy similar al anterior pero el primer cambio es pasar la variable estatica a la parte privada de la clase. Esto impedira que pueda ser accedida directamente y para poder recuperar este valor agregamos un nuevo metodo y este tambien debe ser estatico. Esto es asi porque los datos estaticos deben ser manejados por metodos estaticos. Este metodo nuevo nos devolvera el valor en cantidad. A partir de ahora no podemos modificar el valor de cantidad y ese solo sera afectado por el constructor y el destructor. Y para obtener el valor usaremos el nuevo metodo. Observen que al momento de establecer un valor inicial para la propiedad estatica sigue siendo igual, esto no se vio afectado. En el main, eliminamos todos los llamados directos a cantidad y lo reemplazamos por el nuevo metodo. Si lo compilan y ejecutan deben obtener la misma salida. La unica diferencia como mencionamos anteriormente es que a partir de ahora cantidad solo puede ser afectada al momento de crear o eliminar objetos.
En resumen, hoy hemos visto a static, que es, para que sirve, como se utiliza, las posibilidades que nos brinda, asi como una serie de ejemplos para aplicarlos. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donatión
It’s for site maintenance, thanks!
$1.50
