Está en la página 1de 17

Tabla de contenidos

Introducción

Class Templates
• Implementación de una plantilla de clase
• plantilla de clase que implementa los miembros
• Uso de una clase plantilla

Funciones Template(Plantillas)
• Aplicación de Funciones de Template
• Usar Funciones de Template
Instancias Template

1 1
Clase de especialización de la plantilla
• Plantilla de clase parcial de Especialización

Función de plantilla de Especialización


Parámetros de plantilla miembros estáticos y variables
Plantillas y Amigos
2 2
Introducción

Muchos de los programas en C de uso común de estructuras de datos como pilas, colas y listas. Un programa puede requerir
una cola de clientes y una cola de mensajes. Uno puede fácilmente poner en práctica una cola de clientes, luego tomar el
código existente y poner en práctica una cola de mensajes. El programa crece, y ahora hay una necesidad de una cola de
pedidos. Así que tener la cola de mensajes y que para convertir una cola de pedidos (Copiar, pegar, buscar, reemplazar ????).
1 ¿Necesita hacer algunos cambios en la implementación de la cola? No es una tarea muy fácil, ya que el código se ha
duplicado en muchos lugares. Re-inventando el código fuente no es un enfoque inteligente en un entorno orientado a objetos
que anima a volver a la usabilidad. Parece tener más sentido para poner en práctica una cola que puede contener cualquier
tipo de arbitrariedad en lugar de duplicar el código. ¿Cómo se hace eso? La respuesta es utilizar la parametrización tipo,
más comúnmente conocida como plantillas.
C plantillas permiten implementar un <T> genéricos cola plantilla que tenga un parámetro de tipo T T. puede ser sustituida
por los tipos reales, por ejemplo, la cola <Customers> y C va a generar la clase Queue <Customers>. Cambio de la
2 aplicación de la cola se hace relativamente simple. Una vez que se implementen los cambios en la plantilla de cola <T>, que
se reflejan inmediatamente en las clases de cola <Customers>, la cola <Messages>, y la cola <Orders>.

Las plantillas son muy útiles en la aplicación de genéricos construcciones como vectores, pilas, listas, colas que se pueden
utilizar con cualquier tipo de arbitrariedad. C plantillas proporcionan una forma de re-uso de código fuente en oposición a la
herencia y la composición que proporcionan una forma de re-uso de código objeto.
C proporciona dos tipos de plantillas: plantillas de clase y la función de plantillas. Use la función de plantillas para escribir
3 las funciones genéricas que pueden ser utilizados con tipos arbitrarios. Por ejemplo, uno puede escribir las rutinas de
búsqueda y de clasificación que se puede utilizar con cualquier tipo de arbitrariedad. La Biblioteca de plantillas estándar
algoritmos genéricos han sido aplicados en función de las plantillas, y los contenedores han sido aplicados en las plantillas
de clase.
Las plantillas de función

Función de plantillas de funciones especiales que pueden operar con los tipos genéricos. Esto nos permite crear una
plantilla de función, cuya funcionalidad puede ser adaptado a más de un tipo o clase, sin repetir el código completo
para cada tipo.
En C + + esto se puede lograr utilizando los parámetros de plantilla. Un parámetro de plantilla es una especie de
parámetro que se puede utilizar para pasar de un tipo como argumento: al igual que los parámetros de función
regular puede ser usado para pasar valores a una función, los parámetros de plantilla permitirá pasar también los
tipos a una función. La función de estos modelos pueden usar estos parámetros como si se tratara de cualquier otro
tipo regular. El formato para la función que se declara plantillas con parámetros de tipo es:

template <class identifier> function_declaration;

template <typename identifier> function_declaration;

Una plantilla de función se comporta como una función que puede aceptar los argumentos de muchos tipos
diferentes. En otras palabras, una plantilla de función representa una familia de funciones. Por ejemplo, el estándar
de C + + Biblioteca contiene la plantilla de función max (x, y) que devuelve X o Y, lo que sea mayor. max () puede
ser definida como este, utilizando la siguiente plantilla ingenua:

La única diferencia entre ambos prototipos es el uso de cualquiera de la clase de palabra clave o la palabra clave
class. Su uso es indistinto, ya que ambas expresiones tienen exactamente el mismo significado y se comportan
exactamente de la misma manera.
Por ejemplo, para crear una plantilla de función que devuelve el mayor de dos objetos que podrían utilizar:
1 template <class myType>
2 myType GetMax (myType a,
3 myType b) {
4 return (a>b?a:b);
}

Aquí hemos creado una función de plantilla con myType como parámetro de plantilla. Este parámetro de plantilla representa un tipo que aún no
ha sido especificado, pero que pueden ser utilizados en la función de plantilla como si fuera un tipo regular. Como puede ver, la plantilla de
función GetMax devuelve el mayor de los dos parámetros de este tipo aún por definir.

Para utilizar esta función de plantilla que utilice el siguiente formato para la llamada a la función:

function_name <type> (parameters);


Por ejemplo, para llamar a GetMax para comparar dos valores enteros de tipo int se puede escribir:

Cuando el compilador encuentra esta llamada a una función de plantilla, se utiliza la plantilla para generar automáticamente una función de
reemplazar cada aparición de myType por el tipo pasado como el parámetro de plantilla real (int en este caso) y luego lo llama. Este proceso se
realiza automáticamente por el compilador y es invisible para el programador.
Aquí está el ejemplo completo :

1 int x,y;
2 GetMax <int> (x,y);
6
10
// PRACTICA II.-Funcion template II
#include <iostream>
using namespace std;
template <class T>
T GetMax (T a, T b) {
return (a>b?a:b);
}
int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax(i,j);
n=GetMax(l,m);
cout << k << endl;
cout << n << endl;
return 0;
}
Las clase de plantillas

También tenemos la posibilidad de escribir las plantillas de clase, de manera que una clase puede tener miembros
que utilizan los parámetros de plantilla como los tipos. Por ejemplo:

1 template <class T>


2 class mypair {
3 T values [2];
4 public:
5 mypair (T first, T second)
6 {
7 values[0]=first;
8 values[1]=second;
9 }
};
La clase que acabamos de definir sirve para almacenar dos elementos de cualquier tipo válido. Por ejemplo, si queremos
declarar un objeto de esta clase para almacenar dos valores enteros de tipo int con los valores de 115 y 36 se escribiría:
  mypair<double> myfloats (3.0, 2.18);

Esta misma clase también se utiliza para crear un objeto para almacenar cualquier otro tipo:
  mypair<int> myobject (115, 36);

La función de miembro en la clase anterior plantilla se ha definido en línea dentro de la declaración de la clase en sí. En caso
de que se define una función miembro fuera de la declaración de la plantilla de clase, que siempre debe preceder a la
definición con la plantilla <...> prefijo:
// PRACTICA III.-Class templates
#include <iostream>
using namespace std;
template <class T>
class mypair {
T a, b;
public:
mypair (T first, T second)
{a=first; b=second;}
T getmax ();
};
template <class T>
T mypair<T>::getmax ()
{
T retval;
retval = a>b? a : b;
return retval;
}
int main () {
mypair <int> myobject (100, 75);
cout << myobject.getmax();
return 0;
}
Observe la sintaxis de la definición de la función miembro getmax:

1 template <class T>


T mypair<T>::getmax ()
2

Confundido por T de tantas? Hay tres T's en la presente declaración: El primero es el parámetro de plantilla. El T
segundo se refiere al tipo devuelto por la función. Y la tercera T (la que hay entre paréntesis angulares) es también un
requisito: Se especifica que esta función de parámetro de plantilla es también la clase de parámetro de plantilla.
La especialización de plantilla
Si queremos definir una aplicación diferente para una plantilla cuando un tipo específico se pasa
como parámetro de plantilla, se puede declarar una especialización de esa plantilla.
Por ejemplo, supongamos que tenemos una clase muy simple llamado mycontainer que puede
almacenar un elemento de cualquier tipo y que sólo tiene una función miembro llamada
increase (aumento), lo que aumenta su valor. Sin embargo, encontramos que cuando se
almacena un elemento de tipo char que sería más conveniente tener una aplicación
completamente diferente, con una mayúsculas función miembro, por lo que decidimos declarar
una plantilla de clase para ese tipo de especialización:
8
J

//PRACTICA IV.- Especializacion template


#include <iostream>
using namespace std;
// class template:
template <class T>
class mycontainer {
T element;
public:
mycontainer (T arg) {element=arg;}
T increase () {return ++element;}
};
// class template specialization:
template <>
class mycontainer <char> {
char element;
public:
mycontainer (char arg) {element=arg;}
char uppercase ()
{
if ((element>='a')&&(element<='z'))
element+='A'-'a';
return element;
}
};
int main () {
mycontainer<int> myint (7);
mycontainer<char> mychar ('j');
cout << myint.increase() << endl;
cout << mychar.uppercase() << endl;
return 0;
}
Esta es la sintaxis utilizada en la clase de especialización de la plantilla:

  template <> class mycontainer <char> { ... };


En primer lugar, observe que preceden a la clase de nombre de la plantilla con un
emptytemplate <> lista de parámetros. Esto es para declarar explícitamente como una
especialización de la plantilla.
1 template <class T> class mycontainer { ... };
2 template <> class mycontainer <char> { ... };

Pero más importante que este prefijo, es el <char> parámetro de especialización


después de la clase de nombre de la plantilla. Este parámetro de especialización se
identifica el tipo para los que vamos a declarar una especialización de la plantilla de
clase (char). Notificación de las diferencias entre la clase genérica de plantilla y la
especialización:

La primera línea es el modelo genérico, y la segunda es la especialización.


Cuando declaramos que las especializaciones de una clase de plantilla,
también tenemos que definir todos sus miembros, incluso los que
exactamente igual al modelo genérico de clase, porque no hay una "herencia "
de los miembros de la plantilla genérica a la especialización.
No parámetros de tipo de plantillas para templates

Además de los argumentos de plantilla que están precedidos por la clase o las palabras clave class, que representan los tipos, las
plantillas pueden también tener parámetros regulares tipo, similares a los que se encuentran en funciones. Como un ejemplo,
echar un vistazo a esta clase de plantilla que se utiliza para contener secuencias de elementos:

// PRACTICA V.-secuencia
100template
#include <iostream> 3.1416
using namespace std;
template <class T, int N>
class mysequence {
T memblock [N];
public:
void setmember (int x, T value);
T getmember (int x);
};
template <class T, int N>
void mysequence<T,N>::setmember (int x, T value) {
memblock[x]=value;
}
template <class T, int N>
T mysequence<T,N>::getmember (int x) {
return memblock[x];
}
int main () {
mysequence <int,5> myints;
mysequence <double,5> myfloats;
myints.setmember (0,100);
myfloats.setmember (3,3.1416);
cout << myints.getmember(0) << '\n';
cout << myfloats.getmember(3) << '\n';
return 0;
}
También es posible establecer valores por defecto para la clase o
tipos de parámetros de plantilla. Por ejemplo, si la clase anterior
definición de plantilla han sido:   mysequence<> myseq;

Podríamos crear objetos utilizando la plantilla


  template <class T=char, int N=10> class
predeterminada parámetros al declarar: mysequence {..};

Que sería equivalente a:   mysequence<char,10> myseq;


Plantillas y proyectos con archivos m últiples

Desde el punto de vista del compilador, plantillas de funciones no son normales o las clases. Que se recojan con la
demanda, lo que significa que el código de una función de plantilla no se compila hasta que una creación de instancias
específicas con argumentos de plantilla es necesario. En ese momento, cuando se requiere una creación de instancias, el
compilador genera una función específicamente para los argumentos de la plantilla.

Cuando los proyectos crecen lo habitual es dividir el código de un programa en diferentes archivos de código fuente. En
estos casos, la interfaz y la aplicación son generalmente separados. Teniendo una biblioteca de funciones, como ejemplo,
la interfaz generalmente consiste de las declaraciones de los prototipos de todas las funciones que pueden ser llamados.
Estos son generalmente declarado en el archivo "encabezamiento", con una extensión. H, y la aplicación (la definición de
estas funciones) está en un archivo independiente con el código C + +.

Debido a que las plantillas se compilan en caso necesario, esto obliga a una restricción de proyectos con archivos
múltiples: la aplicación (definición) de una plantilla de clase o función debe estar en el mismo archivo como su declaración.
Eso significa que no podemos separar la interfaz en un archivo de encabezado independiente, y que debe incluir tanto la
interfaz y la aplicación en cualquier archivo que utiliza las plantillas.

Dado que no se genera código hasta que una plantilla se crea una instancia cuando sea necesario, se preparan los
compiladores para permitir la inclusión de más de una vez del mismo archivo de plantilla con las dos declaraciones y
definiciones en un proyecto sin generar errores de vinculación.

También podría gustarte