Templates o plantillas c++
Gracias a c++ podemos definir clases-plantilla: son clases PARAMETRIZABLES por lo general entidades abstractas que se pueden concretar en algo mas concreto. El ejemplo mas claro es de las estructuras de datos tradicionales: Pilas, Listas, Colas, etc..
Esas estructuras pueden contener distintos tipos de datos: enteros, strings, objetos,...
Debemos reescribir la logica de cada estructura para cada tio de dato? NO! Podemos definir una clase plantilla para la Lista, la cola, la pila etc, y luego simplemente invocarlas especificando el tipo de dato. Asi de facil.
Veamos este horrible ejemplo de lista
(atencion a la complicadilla sintaxis)
/**
* Lista.hpp
* Clase que define una estructura de datos lista Generica
*
* Pello Xabier Altadill Izura
*/

#include <iostream.h>

// Asi es como declaramos una clase plantilla
// template <class nombre_generico> class NombreClase
template <class GENERICO> class Lista {

 public:
    // Constructor
    Lista();
    // Constructor
    Lista(GENERICO elemento);

    // Constructor copia
    Lista(Lista const &);
    // Destructor
    ~Lista();

    // agregar elemento
    void agregar(Lista *nodo);
    // se mueve hasta el siguiente dato
    Lista* siguiente();
    // comprueba si existe un elemento
    bool existe(GENERICO dato);

    // comprueba si existe un elemento
    GENERICO getDato() { return this->dato;}

 private:
    // un elemento que apunta a otra lista, asi sucesivamente
    Lista *ladealao;
    // el dato es del tipo GENERICO
    GENERICO dato;

};



Y su implementacion
/**
* Lista.cpp
* Programa que implementa la clase de Lista generica
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -c Lista.cpp
*
*/

#include "Lista.hpp"

// En la implementacion debemos detallar el tipo de dato,
// especificando todo el tema de plantilla, o sea que en lugar
// de poner Lista:: delante de cada funcion debemos poner TODO
// el churro siguiente
// template <class GENERICO> Lista<GENERICO>::nombreFuncion

    // Constructor
    template <class GENERICO> Lista<GENERICO>::Lista() {
        ladealao = 0;
        //dato = 0;
        cout << "Nueva lista creada." << endl;
    }

    // Constructor
    template <class GENERICO> Lista<GENERICO>::Lista(GENERICO elemento) {
        ladealao = 0;
        dato = elemento;
        cout << "Nueva lista creada. Dato inicial: " << dato << endl;
    }

    // Constructor copia
    template <class GENERICO> Lista<GENERICO>::Lista(Lista const & original) {
        ladealao = new Lista;
        ladealao = original.ladealao;
        dato = original.dato;
    }

    // Destructor
    template <class GENERICO> Lista<GENERICO>::~Lista() {
    }

    // agregar elemento: AL LORO con donde se pone el retonno
    template <class GENERICO> void Lista<GENERICO>::agregar(Lista *nodo) {
        nodo->ladealao = this;
        ladealao = 0;
    }

    // se mueve hasta el siguiente dato
     template <class GENERICO> Lista<GENERICO>* Lista<GENERICO>::siguiente() {
         return ladealao;
     }

     //Lista template <class GENERICO> Lista<GENERICO>::siguiente();
    // comprueba si existe un elemento
    template <class GENERICO> bool Lista<GENERICO>::existe(GENERICO dato) {
        return false;
    }


Usando la lista
Y ahora definimos una clase llamada Nombre. Crearemos una lista de nombres.
Este es la definicion
/**
* Nombres.hpp
* Clase que define los nombres. No es mas que una cobaya para probar el template
*
* Pello Xabier Altadill Izura
*/

// Esta clase la usaremos en el template, no hay qeu definir nada en especial


class Nombre {

 public:
    // Constructor
    Nombre():nombre("Jezabel") {
    }
    // Constructor
    Nombre(char *nombre) {
        this->nombre = nombre;
    }
    // Constructor copia
    Nombre(Nombre const &);
    // Destructor
    ~Nombre(){}
    // agregar elemento
    char* getNombre() const { return this->nombre;}

 private:
    // el dato
    char *nombre;
};

Y su implementacion y los ejemplos de uso de plantillas
/**
* Nombres.cpp
* Programa que implementa la clase nombres y utilza los templates
* para crear una lista de nombres.
*
* Pello Xabier Altadill Izura
* Compilando: g++ -o Nombre Lista.o Nombre.cpp
*/

#include "Nombre.hpp"
#include "Lista.hpp"

    // Constructor copia
    Nombre::Nombre(Nombre const & original) {
        nombre = new char;
        nombre = original.getNombre();
    }


// Funcion principal para las pruebas
int main () {
// Asi es como se implementan objetos con clases plantilla
Lista<Nombre> listanombres;
Lista<Nombre> *tmp, *final;
Nombre test = Nombre("Prince");

// podemos definir Listas de cualquier tipo basico
Lista<int> listaenteros;

// guardamos la posicion inicial; final es un puntero, le pasamos la direccion
final = &listanombres;

// vamos a crear unos cuantos NODOS y los añadimos
tmp = new Lista<Nombre>;
tmp->agregar(final);
final = tmp;
// otra mas...
tmp = new Lista<Nombre>;
tmp->agregar(final);
final = tmp;
// otra mas...
tmp = new Lista<Nombre>;
tmp->agregar(final);
final = tmp;

// y ahora recorremos la lista:
tmp = &listanombres;
while (tmp) {
    cout << tmp->getDato().getNombre() << endl;
    tmp = tmp->siguiente();
}

int i;


cin >> i;
return 0;
}


Es un tema complejo pero util.