lunes, 18 de abril de 2011

plantillas en c++ (templates)


En este tutorial voy a exponer una de las características
mas complicadas del C++, las plantillas (en
ingles templates) y para la
demostración usare un problema muy sencillo y fácil de
entender.

Problema: El entandar C++ no especifica un tamaño para los
tipos de variable, solo dice que deben tener un
tamaño mínimo.


Solución: Escribir un programa que muestre el tamaño
de los tipos de variable.


Para saber el tamaño de un tipo o variable
podemos usar el operador sizeof,
que retorna el tamaño en bytes, podríamos multiplicarlo por
8 para saber cuantos bits son, asi que para mostrarlo en pantalla
usaríamos este código:

std::cout << "char " << sizeof (char) * 8;
Pero seria un desperdicio tener que repetir todo
para cada tipo, aquí es donde entran en funcion las plantillas,
este es el programa terminado.



 1 /**********************************************
 2    * Name:     test_type_sizes.cpp
 3    * Created:   19-Abr-2011
 4    * Author:    Gabriel Espinoza
 5      <virtuosonic@users.sourceforge.net>
 6    * License:     MIT
 7    ********************************************/
 8  #include <iostream>
 9  #include <typeinfo>
10  #include <iomanip>
11  
12  using std::cout;
13  using std::endl;
14  using std::cin;
15  using std::setw;
16  using std::setiosflags;
17  using std::ios;
18  
19  template <class T> void print_size()
20  {
21      cout << "  " << setiosflags(ios::left)
22          << setw(12)
23          << typeid(T).name()
24          << resetiosflags(ios::left)
25          << setw(3)<< sizeof (T)*8
26          <<" bits" << endl;
27  }
28  
29  int main()
30  {
31      cout << "types size:" << endl;
32      print_size<bool>();
33      print_size<char>();
34      print_size<short>();
35      print_size<int>();
36      print_size<long>();
37      print_size<float>();
38      print_size<double>();
39      print_size<long double>();
40      cin.get();
41  }

Las primeras 7 lineas son comentarios, en resumen dicen
que el programa lo escribi yo y no me hago responsable
si tu computadora, celular, horno de microondas, tamagochi
o cualquier otro aparato en el que lo pruebes estalla, te asesina,
te deja sin empleo, domina el mundo, se va de la casa caminando,
etc.
De la linea 8 a la 16 declaramos que usaremos
algunas partes de la STL (standard template library(libreria de plantillas estandar))

En las lineas 18 a la 22 encontramos la parte
interesante, es la funcion print_size que hace toda
la accion, seguro ya notaste que no lleva parametros,
esto es porque no trabaja con objetos o variables,
solamente nesecita saber el tipo que debe analizar y
ese tipo es el que se pasa como el parametro de la
plantilla (notese la diferencia entre parametro de plantilla
y parametro de funcion).
Dentro de la funcion main (que es el punto de
inicio del programa) podemos ver el uso de la funcion
print_size, los espacios y la funcion setw son
usados para formatear la salida(hacer que se vean derechas
las letras en la pantalla), setiosflags y resetiosflags
se modifica la alineacion del texto, con typeid(T).name()
sabemos el nombre del tipo de T, el valor retornado por
sizeof lo multiplicamos por 8 para convertirlo a bits.

A algunos autores les gusta comparar las plantillas con la
Herencia Multiple, en mi opinion aunque se parecen, hay
problemas como el anterior que no se pueden resolver con
Herencia multiple, asi que me parece mas apropiado comparar
a las plantillas con el "Pre Procesador de C" (en ingles c
preprocesor o cpp), el ejemplo anterior bien se podria haber
resuelto con macros de cpp, pero al ser un proceso aparte el
compilador no puede localizar errores en macros tan facilmente
y cpp por lo mismo es responsable (en muchos casos) de complicar
el mantenimiento de los programa que lo usan, el mismisimo
Bjarne Stroustrup (el creador de C++) ha declarado que cpp es
redundante y que quisiera verlo abolido. Asi que sugiero usar
plantillas en vez de macros siempre que sea posible.

Nota: Esta solucion no es completamente efectiva
porque segun el estandar C++, el valor retornado por
typeid(T).name() es dependiente de implementacion,
o sea que cada compilador puede retornar el valor que le
de la gana, como gcc (GNU Crap Compiler) que por ejemplo
para long double retorna 'e'.


Bajar el codigo de este programa

2 comentarios:

  1. Me llama mucho la atención el lenguage c++ como orientador de objetos. Si alguna vez tuviera que hacer la implementación, en el modelado de un artefacto como la cámara de calor, con este componente entenderían los clientes muy bien el funcionamiento del mencionado artefacto, para construir por ejemplo los secaderos del grano de cacao. Excelente entrada. Gracias. Cordial saludo: Gustavo Salazar Longas E - mail: salazargustavo279@gmail.com

    ResponderEliminar
  2. Bueno a aprender este lenguaje... me parece que puedo sacar buenos recultados... en softwares... leí que es limitado sólo por la imaginación...

    ResponderEliminar