Anuncios

Hola, a todos sean bienvenidos a mi nuevo post. Hoy continuaremos con el tema iniciado en el post anterior. Ahora hablaremos sobre como utilizar elementos de una plantilla, esto nos permitire pasarlos como valor o referencia y retornarlos como tales, veamos el siguiente ejemplo:

template03.cpp

#include <iostream>

using namespace std;

const int TamanioPredet = 10;
 
class Animal
{
public:
 	Animal(int);
 	Animal();
 	~Animal();
 	int ObtenerPeso() const { return suPeso; }
 	void AsignarPeso(int elPeso) { suPeso = elPeso; }
 	friend ostream & operator << (ostream &, const Animal &);
private:
 	int suPeso;
};

ostream & operator << (ostream & elFlujo, const Animal & elAnimal)
{
 	elFlujo << elAnimal.ObtenerPeso();
 	return elFlujo;
}

Animal::Animal(int peso):
	suPeso(peso)
 	{
 	// cout << "Animal(int)\n";
 	}

Animal::Animal():
 	suPeso(0)
 	{
 	// cout << "Animal()\n";
 	}

Animal::~Animal()
{
 	// cout << "Se destruyo un animal...\n";
}

template < class T >
class Arreglo
{
public:
 	Arreglo(int suTamanio = TamanioPredet);
 	Arreglo(const Arreglo & rhs);
 	~Arreglo() { delete [] apTipo; }
 	Arreglo &operator= (const Arreglo &);
 	T & operator[] (int desplazamiento) { return apTipo[ desplazamiento ]; }
 	const T &operator[](int desplazamiento) const 
		{ return apTipo[ desplazamiento ]; }
 	int ObtenerTamanio() const { return suTamanio; }
 	friend ostream & operator<< (ostream & salida, 
			const Arreglo< T > & elArreglo)
 		{
 		for(int i = 0; i < elArreglo.ObtenerTamanio(); i++)
 			salida << "[ " << i << " ] " << elArreglo[ i ] << endl;
 		return salida;
 		}
private:
 	T * apTipo;
 	int suTamanio;
};

template < class T >
Arreglo< T >::Arreglo(int tamanio):
 	suTamanio(tamanio)
 	{
 		apTipo = new T[ tamanio ];
 		for(int i = 0; i < tamanio; i++)
 			apTipo[ i ] = 0;
 	}
 
template < class T >
Arreglo< T >::Arreglo(const Arreglo & rhs)
{
 	suTamanio = rhs.ObtenerTamanio();
 	apTipo = new T[ suTamanio ];
 	for(int i = 0; i < suTamanio; i++)
 	apTipo[ i ] = rhs[ i ];
}

template < class T >
Arreglo< T > & Arreglo< T >::operator=(const Arreglo & rhs)
{
 	if (this == &rhs)
 		return *this;
 	delete [] apTipo;
 	suTamanio = rhs.ObtenerTamanio();
 	apTipo = new T[ suTamanio ];
 	for(int i = 0; i < suTamanio; i++)
 		apTipo[ i ] = rhs[ i ];
 	return *this;
}

void FuncionLlenarInt(Arreglo< int > & elArreglo);
void FuncionLlenarAnimal(Arreglo< Animal > & elArreglo);

int main()
{
 	Arreglo< int > arregloInt;
 	Arreglo< Animal > arregloAnimal;
	FuncionLlenarInt(arregloInt);
 	FuncionLlenarAnimal(arregloAnimal);
 	cout << "arragloInt...\n" << arregloInt;
 	cout << "arregloAnimal..\n" << arregloAnimal << endl;
	return 0;
}

void FuncionLlenarInt(Arreglo< int > & elArreglo)
{
 	bool Detener = false;
 	int desplazamiento, valor;
	while(!Detener)
 	{
 		cout << "Escriba un desplazamiento [0-9] ";
 		cout << " y un valor. (-1 para Detener): ";
 		cin >> desplazamiento >> valor;
 		if (desplazamiento < 0)
 			break;
 		if (desplazamiento > 9)
 		{
 			cout << "++++ Utilice valores entre 0 y 9++++\n";
 			continue;
 		}
 		elArreglo[ desplazamiento ] = valor;
 	}
}

void FuncionLlenarAnimal(Arreglo< Animal > & elArreglo)
{
 	Animal *apAnimal;
	for(int i = 0; i < elArreglo.ObtenerTamanio(); i++)
 	{
 		apAnimal = new Animal;
 		apAnimal->AsignarPeso(i * 100);
 		elArreglo[ i ] = *apAnimal;
 		delete apAnimal;
 	}
}
Anuncios

En este programa vamos a lograr dos objetivos, almacenar un arreglo de numeros enteros, como vimos en el ultimo ejemplo del post anterior, y otro donde se almacenara el peso de los animales, primero analicemos las modificaciones en la clase Animal:

class Animal
{
public:
 	Animal(int);
 	Animal();
 	~Animal();
 	int ObtenerPeso() const { return suPeso; }
 	void AsignarPeso(int elPeso) { suPeso = elPeso; }
 	friend ostream & operator << (ostream &, const Animal &);
private:
 	int suPeso;
};
Anuncios

Para este bloque vamos a tener una funcion llamada AsignarPeso() y una funcion “amiga” para utilizar el operador <<, en este caso despues definiremos los constructores, el destructor y la funcion “amiga”, luego tendremos el template con sus definiciones, agregaremos dos lineas donde crearemos los prototipos de dos funciones:

void FuncionLlenarInt(Arreglo< int > & elArreglo);
void FuncionLlenarAnimal(Arreglo< Animal > & elArreglo);
Anuncios

Estas dos funciones se van a encargar de llenar los Arreglos creados, la primera llenara el Arreglo de enteros y la otra llenara el peso de los animales, veamos el main():

int main()
{
 	Arreglo< int > arregloInt;
 	Arreglo< Animal > arregloAnimal;
	FuncionLlenarInt(arregloInt);
 	FuncionLlenarAnimal(arregloAnimal);
 	cout << "arragloInt...\n" << arregloInt;
 	cout << "arregloAnimal..\n" << arregloAnimal << endl;
	return 0;
}
Anuncios

Cuando se llama a las funciones, en el primer caso se interactua con el usuario porque se le solicita el ingreso de los datos, como en el ultimo ejemplo del post anterior, y en la segunda funcion lo confeccionara automaticamente, veamos la primera funcion:

void FuncionLlenarInt(Arreglo< int > & elArreglo)
{
 	bool Detener = false;
 	int desplazamiento, valor;
	while(!Detener)
 	{
 		cout << "Escriba un desplazamiento [0-9] ";
 		cout << " y un valor. (-1 para Detener): ";
 		cin >> desplazamiento >> valor;
 		if (desplazamiento < 0)
 			break;
 		if (desplazamiento > 9)
 		{
 			cout << "++++ Utilice valores entre 0 y 9++++\n";
 			continue;
 		}
 		elArreglo[ desplazamiento ] = valor;
 	}
}
Anuncios

Como pueden ver en este caso volvemos a pedirle al usuario ingresar dos datos, uno de posicion (desplazamiento) y otro de valor, cerrando con el valor -1, esta se encargara de llenar el Arreglo de enteros, esta es la otra funcion:

void FuncionLlenarAnimal(Arreglo< Animal > & elArreglo)
{
 	Animal *apAnimal;
	for(int i = 0; i < elArreglo.ObtenerTamanio(); i++)
 	{
 		apAnimal = new Animal;
 		apAnimal->AsignarPeso(i * 100);
 		elArreglo[ i ] = *apAnimal;
 		delete apAnimal;
 	}
}
Anuncios

En este caso a traves del bucle for, crearemos un apuntador de la clase Animal y le asignaremos un peso por medio de AsignarPeso() y luego lo asignara al Arreglo. Veamos la salida del codigo:

tinchicus@dbn001dsk:~/lenguaje/c++$ ./template03
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 0 9
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 1 10
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 2 8
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 3 4
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): -1 -1
arragloInt…
[ 0 ] 9
[ 1 ] 10
[ 2 ] 8
[ 3 ] 4
[ 4 ] 0
[ 5 ] 0
[ 6 ] 0
[ 7 ] 0
[ 8 ] 0
[ 9 ] 0
arregloAnimal..
[ 0 ] 0
[ 1 ] 100
[ 2 ] 200
[ 3 ] 300
[ 4 ] 400
[ 5 ] 500
[ 6 ] 600
[ 7 ] 700
[ 8 ] 800
[ 9 ] 900

tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

En este caso, como pueden ver utilizamos el template para crear un Arreglo del tipo entero y otro de la clase Animal, observen como se pudieron utilizar el operador << tanto para los arreglos de Animal como de enteros, ahora veamos la salida obtenida al sacar los comentarios de las constructores y el destructor de Animal y al ejecutarlo obtendremos esta salida:

tinchicus@dbn001dsk:~/lenguaje/c++$ ./template03
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Animal(int)
Se destruyo un animal…
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 1 2
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 7 10
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 5 6
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): -1 -1
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
arragloInt…
[ 0 ] 0
[ 1 ] 2
[ 2 ] 0
[ 3 ] 0
[ 4 ] 0
[ 5 ] 6
[ 6 ] 0
[ 7 ] 10
[ 8 ] 0
[ 9 ] 0
arregloAnimal..
[ 0 ] 0
[ 1 ] 100
[ 2 ] 200
[ 3 ] 300
[ 4 ] 400
[ 5 ] 500
[ 6 ] 600
[ 7 ] 700
[ 8 ] 800
[ 9 ] 900
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

Observen todos los procesos creados detras, esto podria crearnos grandes inconvenientes de performance y tambien con la cantidad de memoria, esto es porque cada vez que un objeto es agregado a un Arreglo se llama al constructor predeterminado del objeto, esto ocasiona agregar el valor cero a cada miembro del arreglo, por cada llamada al operador = predeterminado de Animal nos genera un objeto Animal temporal usando el constructor, esto es utilizado como el lado derecho del operador = y luego se destruye, esta perdida de tiempo puede ser evitado por medio de un constructor especial como veremos en el siguiente codigo:

template04.cpp

#include <iostream>

using namespace std;

const int TamanioPredet = 10;
 
class Animal
{
public:
 	Animal(int);
 	Animal();
 	~Animal();
 	int ObtenerPeso() const { return suPeso; }
 	void AsignarPeso(int elPeso) { suPeso = elPeso; }
 	friend ostream & operator << (ostream &, const Animal &);
private:
 	int suPeso;
};

ostream & operator << (ostream & elFlujo, const Animal & elAnimal)
{
 	elFlujo << elAnimal.ObtenerPeso();
 	return elFlujo;
}

Animal::Animal(int peso):
 	suPeso(peso)
 	{
 		cout << "Animal(int)\n";
 	}

Animal::Animal():
 	suPeso(0)
 	{
 		cout << "Animal()\n";
 	}

Animal::~Animal()
 	{
 		cout << "Se destruyo un animal...\n";
 	}

template < class T >
class Arreglo
{
public:
 	Arreglo(int suTamanio = TamanioPredet);
 	Arreglo(const Arreglo & rhs);
 	~Arreglo() { delete [] apTipo; }
 	Arreglo &operator= (const Arreglo &);
 	T & operator[] (int desplazamiento) { return apTipo[ desplazamiento ]; }
 	const T &operator[](int desplazamiento) const
 		{ return apTipo[ desplazamiento ]; }
 	int ObtenerTamanio() const { return suTamanio; }
 	friend ostream & operator<< (ostream & salida, const Arreglo< T > & elArreglo)
 	{
 		for(int i = 0; i < elArreglo.ObtenerTamanio(); i++)
 			salida << "[ " << i << " ] " << elArreglo[ i ] << endl;
 		return salida;
 	}
private:
 	T * apTipo;
 	int suTamanio;
};

template < class T >
Arreglo< T >::Arreglo(int tamanio):
 	suTamanio(tamanio)
 	{
 		apTipo = new T[ tamanio ];
 		for(int i = 0; i < tamanio; i++)
 		apTipo[ i ] = (T)0;
 	}

template < class T >
Arreglo< T >::Arreglo(const Arreglo & rhs)
{
 	suTamanio = rhs.ObtenerTamanio();
 	apTipo = new T[ suTamanio ];
 	for(int i = 0; i < suTamanio; i++)
 		apTipo[ i ] = rhs[ i ];
}

template < class T >
Arreglo< T > & Arreglo< T >::operator=(const Arreglo & rhs)
{
 	if (this == &rhs)
 		return *this;
 	delete [] apTipo;
 	suTamanio = rhs.ObtenerTamanio();
 	apTipo = new T[ suTamanio ];
 	for(int i = 0; i < suTamanio; i++)
 		apTipo[ i ] = rhs[ i ];
 	return *this;
}

template<>
Arreglo< Animal >::Arreglo(int TamanioArregloAnimal):
 	suTamanio(TamanioArregloAnimal)
 	{
 		apTipo = new Animal[ TamanioArregloAnimal ];
 	}

void FuncionLlenarInt(Arreglo< int > & elArreglo);
void FuncionLlenarAnimal(Arreglo< Animal > & elArreglo);

int main()
{
 	Arreglo< int > arregloInt;
 	Arreglo< Animal > arregloAnimal;
	FuncionLlenarInt(arregloInt);
	FuncionLlenarAnimal(arregloAnimal);
 	cout << "arragloInt...\n" << arregloInt;
 	cout << "arregloAnimal..\n" << arregloAnimal << endl;
	return 0;
}

void FuncionLlenarInt(Arreglo< int > & elArreglo)
{
 	bool Detener = false;
 	int desplazamiento, valor;
	while(!Detener)
 	{
 		cout << "Escriba un desplazamiento [0-9] ";
 		cout << " y un valor. (-1 para Detener): ";
 		cin >> desplazamiento >> valor;
 		if (desplazamiento < 0)
 			break;
 		if (desplazamiento > 9)
 		{
 			cout << "++++ Utilice valores entre 0 y 9++++\n";
 			continue;
 		}
 		elArreglo[ desplazamiento ] = valor;
 	}
}

void FuncionLlenarAnimal(Arreglo< Animal > & elArreglo)
{
 	Animal *apAnimal;
	for(int i = 0; i < elArreglo.ObtenerTamanio(); i++)
 	{
 		apAnimal = new Animal;
 		apAnimal->AsignarPeso(i * 100);
 		elArreglo[ i ] = *apAnimal;
 		delete apAnimal;
 	}
}
Anuncios

Como pueden ver en este codigo solamente vamos a agregar este bloque:

template<>
Arreglo< Animal >::Arreglo(int TamanioArregloAnimal):
 	suTamanio(TamanioArregloAnimal)
 	{
 		apTipo = new Animal[ TamanioArregloAnimal ];
 	}
Anuncios

Donde definiremos un template sin nombre, esto es para informarle al compilador que el siguiente bloque es perteneciente a un template, donde definiremos el constructor de Arreglo(int) para el objeto Animal, esto nos evitara el error descripto antes del codigo, la salida de nuestro nuevo programa es:

tinchicus@dbn001dsk:~/lenguaje/c++$ ./template04
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Animal()
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 7 3
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 4 5
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): 2 10
Escriba un desplazamiento [0-9]  y un valor. (-1 para Detener): -1 -1
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
Animal()
Se destruyo un animal…
arragloInt…
[ 0 ] 0
[ 1 ] 0
[ 2 ] 10
[ 3 ] 0
[ 4 ] 5
[ 5 ] 0
[ 6 ] 0
[ 7 ] 3
[ 8 ] 0
[ 9 ] 0
arregloAnimal..
[ 0 ] 0
[ 1 ] 100
[ 2 ] 200
[ 3 ] 300
[ 4 ] 400
[ 5 ] 500
[ 6 ] 600
[ 7 ] 700
[ 8 ] 800
[ 9 ] 900
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
Se destruyo un animal…
tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

Como pueden ver los constructores y destructores de nuestro programa se siguen utilizando pero la diferencia va a estar al principio donde no desperdiciara tiempo y memoria en crear y destruir los nuevos objetos creados para Animal, para esto sirve en este caso el constructor especializado. ahora hablaremos sobre miembros estaticos y planitllas, estos pueden ser utilzados dentro del mismo y por ende nos creara un dato estatico por cada objeto creado, veamoslo a traves del siguiente ejemplo:

template05.cpp

#include <iostream>

using namespace std;

const int TamanioPredet = 3;
 
class Animal
{
public:
 	Animal(int);
 	Animal();
 	~Animal();
 	int ObtenerPeso() const { return suPeso; }
 	void AsignarPeso(int elPeso) { suPeso = elPeso; }
 	friend ostream & operator << (ostream &, const Animal &);
private:
 	int suPeso;
};

ostream & operator << (ostream & elFlujo, const Animal & elAnimal)
{
 	elFlujo << elAnimal.ObtenerPeso();
 	return elFlujo;
}

Animal::Animal(int peso):
 	suPeso(peso)
 	{
 	// cout << "Animal(int)\n";
 	}

Animal::Animal():
 	suPeso(0)
 	{
 	// cout << "Animal()\n";
 	}

Animal::~Animal()
 	{
 	// cout << "Se destruyo un animal...\n";
 	}

template < class T >
class Arreglo
{
public:
 	Arreglo(int suTamanio = TamanioPredet);
 	Arreglo(const Arreglo & rhs);
 	~Arreglo() { delete [] apTipo; suNumeroArreglos--; }
 	Arreglo &operator= (const Arreglo &);
 	T & operator[] (int desplazamiento) { return apTipo[ desplazamiento ]; }
 	const T &operator[](int desplazamiento) const
 		{ return apTipo[ desplazamiento ]; }
 	int ObtenerTamanio() const { return suTamanio; }
 	static int ObtenerNumeroArreglos() { return suNumeroArreglos; }
 	friend ostream & operator<< (ostream & salida, const Arreglo< T > & elArreglo)
 	{
 		for(int i = 0; i < elArreglo.ObtenerTamanio(); i++)
 			salida << "[ " << i << " ] " << elArreglo[ i ] << endl;
 		return salida;
 	}
private:
 	T * apTipo;
 	int suTamanio;
 	static int suNumeroArreglos;
};

template< class T >
int Arreglo< T >::suNumeroArreglos = 0;

template < class T >
Arreglo< T >::Arreglo(int tamanio):
 	suTamanio(tamanio)
 	{
 		apTipo = new T[ tamanio ];
 		for(int i = 0; i < tamanio; i++)
 			apTipo[ i ] = (T)0;
 		suNumeroArreglos++;
 	}

template < class T >
Arreglo< T >::Arreglo(const Arreglo & rhs)
{
 	suTamanio = rhs.ObtenerTamanio();
 	apTipo = new T[ suTamanio ];
 	for(int i = 0; i < suTamanio; i++)
 		apTipo[ i ] = rhs[ i ];
 	suNumeroArreglos++;
}

template < class T >
Arreglo< T > & Arreglo< T >::operator=(const Arreglo & rhs)
{
 	if (this == &rhs)
 		return *this;
 	delete [] apTipo;
 	suTamanio = rhs.ObtenerTamanio();
 	apTipo = new T[ suTamanio ];
 	for(int i = 0; i < suTamanio; i++)
 		apTipo[ i ] = rhs[ i ];
 	return *this;
}

int main()
{
 	cout << Arreglo< int >::ObtenerNumeroArreglos();
 	cout << " arreglos de Enteros.\n";
 	cout << Arreglo< Animal >::ObtenerNumeroArreglos();
 	cout << " arreglos de Animales.\n";
	Arreglo< int > arregloInt;
 	Arreglo< Animal > arregloAnimal;
	cout << arregloInt.ObtenerNumeroArreglos();
 	cout << " arreglos de Enteros.\n";
 	cout << arregloAnimal.ObtenerNumeroArreglos();
 	cout << " arreglos de Animales.\n";
	Arreglo< int > *apArregloInt = new Arreglo< int >;
	cout << Arreglo< int >::ObtenerNumeroArreglos();
 	cout << " arreglos de Enteros.\n";
 	cout << Arreglo< Animal >::ObtenerNumeroArreglos();
 	cout << " arreglos de Animales.\n";
	delete apArregloInt;
	cout << Arreglo< int >::ObtenerNumeroArreglos();
 	cout << " arreglos de Enteros.\n";
 	cout << Arreglo< Animal >::ObtenerNumeroArreglos();
 	cout << " arreglos de Animales.\n";
	return 0;
}
Anuncios

En este codigo vamos a crear una dato estatico encargada de contar la cantidad de Arreglos creados por medio de nuestra template, lo primero que modificamos va a ser nuestro template de la siguiente forma:

template < class T >
class Arreglo
{
public:
 	Arreglo(int suTamanio = TamanioPredet);
 	Arreglo(const Arreglo & rhs);
 	~Arreglo() { delete [] apTipo; suNumeroArreglos--; }
 	Arreglo &operator= (const Arreglo &);
 	T & operator[] (int desplazamiento) { return apTipo[ desplazamiento ]; }
 	const T &operator[](int desplazamiento) const
 		{ return apTipo[ desplazamiento ]; }
 	int ObtenerTamanio() const { return suTamanio; }
 	static int ObtenerNumeroArreglos() { return suNumeroArreglos; }
 	friend ostream & operator<< (ostream & salida, const Arreglo< T > & elArreglo)
 	{
 		for(int i = 0; i < elArreglo.ObtenerTamanio(); i++)
 			salida << "[ " << i << " ] " << elArreglo[ i ] << endl;
 		return salida;
 	}
private:
 	T * apTipo;
 	int suTamanio;
 	static int suNumeroArreglos;
};
Anuncios

Hablemos de atras hacia adelante, en la parte privada vamos a declarar la variable estatica de tipo entero llamado suNumeroArreglos, en la parte publica tambien vamos a crear una funcion del tipo estatica para obtener el valor de suNumeroArreglos y por ultimo vamos a ver al destructor donde no solo eliminaremos a apTipo sino a su vez restaremos el valor de suNumeroArreglos. Despues establecemos el valor para la variable estatica, como se debe hacer con todos los tipos estaticos:

template< class T >
int Arreglo< T >::suNumeroArreglos = 0;
Anuncios

Como vimos hasta ahora, primero definimos el template a utilizar y luego estableceremos el valor, ahora veamos las modificaciones de los constructores:

template < class T >
Arreglo< T >::Arreglo(int tamanio):
 	suTamanio(tamanio)
 	{
 		apTipo = new T[ tamanio ];
 		for(int i = 0; i < tamanio; i++)
 			apTipo[ i ] = (T)0;
 		suNumeroArreglos++;
 	}

template < class T >
Arreglo< T >::Arreglo(const Arreglo & rhs)
{
 	suTamanio = rhs.ObtenerTamanio();
 	apTipo = new T[ suTamanio ];
 	for(int i = 0; i < suTamanio; i++)
 		apTipo[ i ] = rhs[ i ];
 	suNumeroArreglos++;
}
Anuncios

Como pueden ver en los dos bloques lo unico agregado es un sumador para cada vez que se haga un nuevo objeto del tipo Arreglo incremente el valor de la variable estatica suNumeroArreglos, esto es para cualquier tipo de dato relacionado en Arreglo. Despues en el main(), en el primer bloque mostraremos los valores de suNumeroArreglos, luego crearemos un Arreglo para el tipo entero y otro para la clase Animal, en el siguiente bloque mostraremos los nuevos valores de suNumeroArreglos, volvemos a crear otro objeto de Arreglo del tipo entero, en el proximo bloque vemos los nuevos valores de suNumeroArreglos, y por ultimo eliminamos el ultimo Arreglo creado para finalmente mostrar los valores de suNumeroArreglos, les paso la salida:

tinchicus@dbn001dsk:~/lenguaje/c++$ ./template05
0 arreglos de Enteros.
0 arreglos de Animales.
1 arreglos de Enteros.
1 arreglos de Animales.
2 arreglos de Enteros.
1 arreglos de Animales.
1 arreglos de Enteros.
1 arreglos de Animales.
tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

Observen como puede verse las primeras dos lineas donde no existe ningun tipo de Arreglo, en las siguientes dos lineas como se incrementaron, en las otras dos lineas como se incrementa uno solo (enteros) y por ultimo la resta del valor de arreglos de enteros. Hasta aqui hemos visto miembros estaticos y plantillas, hablemos un poco sobre la libreria estandar de planillas (STL). esta es una caracteristica de C++ y basicamente es una biblioteca basada en clases contenedoras de plantillas, esta compuesta por vectores, listas, colas y pilas pero tambien incluye un par de algoritmos llamados ordenamiento y busqueda. El gran objetivo de STL (Libreria estandar de plantillas) es ofrecer una alternativa para no reinventar estos requerimientos comunes pero no ahondaremos mas en detalles porque lo dejaremos para un proximo post.

Anuncios

Hasta aqui hemos visto lo faltante de los templates, hemos utilizado elementos de una plantilla para poder llevar y traer distintos tipos de objetos como vimos en el ejemplo asignamos el tipo entero y el de clase Animal para utilizarlo en dos metodos. Luego observamos como este metodo nos produce mucha creacion de procesos por la cantidad de los arreglos creados por medio del operador=, para evitar eso luego utilizamos lo llamado funciones especializadas donde nosotros hacemos un nuevo metodo donde declaramos especificamente para cual tipo de objeto y asi poder evitar la creacion innecesaria de objetos, y por ultimo hemos visto como utilizar una variable y una funcion del tipo estatica con nuestras plantillas y vimos brevemente que es la STL, libreria estandar de plantillas, la cual ahondaremos mas en un proximo post. Espero les haya sido util, 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.

Anuncios

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00