Bienvenidos sean a este post, hoy veremos como utilizar elementos estaticos en nuestras plantillas.
Tal como vimos hasta ahora, si son seguidores de los posts anteriores, todo podemos usarlo a nuestra conveniencia. Por esta razon, los elementos estaticos tambien pueden ser usados en nuestras plantillas. Vamos a tomar el codigo que estuvimos trabajando en los posts anteriores y vamos a realizar una serie de modificaciones:
#include <iostream>
const int tamanoPredet = 5;
class Animal
{
public:
Animal(int peso): suPeso(peso) {}
Animal(): suPeso(0) {}
~Animal() {}
int GetPeso() const { return suPeso; }
friend std::ostream & operator<< (std::ostream &, const Animal &);
private:
int suPeso;
};
std::ostream & operator << (std::ostream & salida, const Animal & animal)
{
salida << animal.GetPeso();
return salida;
}
template <class T>
class Arreglo
{
public:
Arreglo(int tamano = tamanoPredet);
Arreglo(const Arreglo & rhs);
~Arreglo()
{
delete [] pTipo;
cantidadArreglos--;
}
Arreglo & operator= (const Arreglo &);
T & operator[] (int pos) { return pTipo[ pos ]; }
const T & operator[] (int pos) const { return pTipo[ pos ]; }
int largo() const { return tamano; }
static int GetCantidad() { return cantidadArreglos; }
friend std::ostream & operator<< (std::ostream & salida,
Arreglo< T > & arreglo) {
for(int i=0; i < arreglo.largo(); i++)
salida << "[" << i << "]" << arreglo[i] << "\n";
return salida;
}
private:
T * pTipo;
int tamano;
static int cantidadArreglos;
};
template <class T>
int Arreglo< T >::cantidadArreglos = 0;
template <class T>
Arreglo< T >::Arreglo(int tam): tamano(tam)
{
pTipo = new T[ tam ];
for(int i=0; i < tam; i++)
pTipo[i] = 0;
cantidadArreglos++;
}
template <class T>
Arreglo< T >::Arreglo(const Arreglo & rhs)
{
tamano = rhs.largo();
pTipo = new T[tamano];
for(int i=0; i < tamano; i++)
pTipo[i] = rhs[i];
cantidadArreglos++;
}
template <class T>
Arreglo< T > & Arreglo< T >::operator=(const Arreglo & rhs)
{
if (this == &rhs)
return *this;
delete [] pTipo;
tamano = rhs.largo();
pTipo = new T[ tamano ];
for(int i=0; i < tamano; i++)
pTipo[i] = rhs[i];
return *this;
}
void chequear()
{
std::cout << Arreglo< Animal >::GetCantidad();
std::cout << " de arrays Animal\n";
std::cout << Arreglo< int >::GetCantidad();
std::cout << " de arrays Enteros\n";
}
int main()
{
chequear();
Arreglo< int > arregloInt;
Arreglo< Animal > arregloAni;
chequear();
Arreglo< int > *pEntero = new Arreglo< int >;
chequear();
delete pEntero;
chequear();
return 0;
}
Para ahondar en los detalles de como es la plantilla usada aqui les recomiendo ver este post, aqui solo veremos algunos y otros mencionaremos muy superficialmente. La clase Animal la usaremos para poder agregar un tipo distinto y propio en nuestra plantilla. En ella tendremos una propiedad para el peso del mismo en la parte privada. En la parte publica Tendremos un destructor y dos constructores asi como tambien un metodo para obtener el valor asignado a suPeso. Pero en esta ocasion agregaremos una funcion amiga de esta clase. Esta funcion hara una sobrecarga del operador << y cada vez que lo usemos en un objeto de esta clase nos mostrara el valor de suPeso.
Lo siguiente es la plantilla que usaremos para crear los arrays de distintos tipos. Es muy similar a la vista en el post anterior pero agregaremos un par de cosas. La primera es agregar en la parte privada una propiedad de tipo estatica para contar la cantidad de arrays que generemos desde esta plantilla. En el destructor agregamos una operacion para disminuir el valor de esta propiedad por cada elemento que eliminemos. A su vez agregamos un nuevo metodo que nos devuelve el valor en la propiedad estatica. Por ultimo, en ambos constructores agregamos una operacion para incrementar a cantidadArreglos por cada uno que generemos. La definicion restante es para la sobrecarga del operador = cada vez que lo usemos en nuestro objetos.
Aqui agregaremos una funcion para devolver la cantidad de objetos creados para dos tipos de arrays mediante el llamado GetCantidad. Esto lo utilizaremos a continuacion en el main.
En el main, primero llamaremos a la funcion anterior. Luego crearemos dos objetos de tipo Arreglo. Uno sera de tipo Animal y otro de tipo int. Para despues nuevamente llamar a chequear. Creamos un puntero de tipo Arreglo< int > y llamar nuevamente a chequear. Para luego borrar el puntero anterior y volver a llamar a chequear. Compilemos y veamos como es la salida:
$ ./plantilla
0 de arrays Animal
0 de arrays Enteros
1 de arrays Animal
1 de arrays Enteros
1 de arrays Animal
2 de arrays Enteros
1 de arrays Animal
1 de arrays Enteros
$
Observen como al inicio no tenemos ninguno. Luego tenemos el incremento en cada objeto, y despues el incremento de uno solo. Esto es asi porque cada objeto es distinto del otro y cada uno tiene su propio control. Por eso cuando borramos el puntero vuelven a tener el mismo valor.
En resumen, hoy hemos visto a template y static, como se utilizan, como se aplican, asi como tambien un ejemplo practico para verlo en accion. 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.