Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Plantillas (Templates) • Clases genéricas pueden ser contenedores de objetos cuyo tipo no es de interés. • Se usa el tipo de objeto como parámetro, que es especificado por el usuario en el momento de declarar una variable 3.6 Templates en C++ Clases y funciones genéricas 1 III-2 Departamento de Informática Universidad Técnica Federico Santa María Departamento de Informática Lenguajes de Programación Ejemplo Sencillo (1) Ejemplo Sencillo (2) template <class T> class stack { T* base; T* tope; int max; public: stack (int s) { base = tope = new T[ max = s];} ~stack() { delete [] base; } int push (T a) { if ((tope-base)== max) return -1; *tope++ = a; return 0 ; } int pop(T& a) { a = *--tope; return (base == tope) ? 0 : -1;} }; … stack<char> s(100); III-3 Departamento de Informática Universidad Técnica Federico Santa María Lenguajes de Programación Universidad Técnica Federico Santa María • En el ejemplo anterior la definición de funciones miembros es in-line. • Para definirlas externamente se usa: template< class T > void stack<T>:: push(T a) { if((tope-base)== max ) return -1; *tope++ = a; return 0; } template< class T> int stack<T>::pop(T& a) { a = *--tope; return (base == tope) ? 0 : -1; } III-4 Departamento de Informática Lenguajes de Programación Lenguajes de Programación Universidad Técnica Federico Santa María Ejemplo: Lista Genérica (1/4) Ejemplo: Lista Genérica (2/4) class enlace { friend class lista_base; enlace* prox; enlace() { prox=0; } enlace(enlace* p) { prox=p; } }; • Listas consisten básicamente de una cadena de nodos que son contenedores de información. • Para implementar listas genéricas se usará la estrategia de: class lista_base { enlace* cabeza; // ... protected : int insertar(enlace*); int agregar(enlace*); enlace* sacar (); // ... }; – Definir un nodo y una lista que implemente los algoritmos de manipulación de sus nodos – Derivando ambos se definen plantillas que permiten instanciar listas contenedoras de diferentes tipos de datos III-5 // constructor #1 // constructor #2 // en la cabeza // en la cola // saca y retorna cabeza III-6 Departamento de Informática Universidad Técnica Federico Santa María Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Ejemplo: Lista Genérica (3/4) Ejemplo: Lista Genérica (4/4) template< class T > class enlace_T : public enlace { friend class lista_T<T>; T info; enlace_T(const T& a) : info (a) {} }; template< class T > class lista_T : private lista_base { public: void insertar(const T& a) {lista_base::insertar(new enlace_T<T>(a));} void agregar (const T& a) {lista_base::agregar( new enlace_T<T>(a));} T sacar(); // ... }; III-7 template< class T > T lista_T<T>::sacar() { enlace_T<T>* nodo = (enlace_T<T>*) lista_base::sacar(); T i = nodo->info; delete nodo; return i ; } void f( int i) { lista_T< int> l1; lista_T< int> l2; l1.insertar(i); l2.insertar(i-1); //… } Departamento de Informática Universidad Técnica Federico Santa María Lenguajes de Programación III-8 Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Comentarios sobre el Ejemplo Lenguajes de Programación Plantilla de Funciones template< class T> void bubble_ sort(Vector<T>& v) { unsigned int n = v.size(); • La lista genérica que se ha definido sirve para contener cualquier tipo de dato. • Muchas veces es necesario procesar todos los elementos de la lista • La definición de un iterador es una buena abstracción para ir obteniendo todos los valores de la lista sin ver su estructura for ( int i=0; i<n-1; i++) for (int j=n-1; i<j; j--) if ((v[j] < v[j-1]) { // intercambiar T tmp = v[j]; v[j] = v[j-1]; v[j-1] = tmp; } } Funcionará siempre y cuando T defina el operador < III-9 III-10