Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
✐<br />
✐<br />
✐<br />
“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 481 — #519<br />
✐<br />
16.2. Un vistazo a las plantillas<br />
Esta es una implem<strong>en</strong>tación bastante efici<strong>en</strong>te, porque nunca se g<strong>en</strong>eran los números<br />
más de una vez. Se usa un array static de int, y se basa <strong>en</strong> el hecho de<br />
que el compilador inicializará el array estático a cero. El primer bucle for mueve el<br />
índice i a la primera posición del array que sea cero, <strong>en</strong>tonces un bucle while añade<br />
números Fibonacci al array hasta que se alcance el elem<strong>en</strong>to deseado. Hay que<br />
hacer notar que si los números Fibonacci hasta el elem<strong>en</strong>to n ya están inicializados,<br />
<strong>en</strong>tonces también se salta el bucle while.<br />
16.1.1. La necesidad de los cont<strong>en</strong>edores<br />
Obviam<strong>en</strong>te, una pila de <strong>en</strong>teros no es una herrami<strong>en</strong>ta crucial. La necesidad real<br />
de los cont<strong>en</strong>edores vi<strong>en</strong>e cuando se empizan a crear objetos <strong>en</strong> el montón (heap)<br />
usando new y se destruy<strong>en</strong> con delete. En un problema g<strong>en</strong>eral de programación<br />
no se sab<strong>en</strong> cuantos objetos van a ser necesarios cuando se está escribi<strong>en</strong>do el programa.<br />
Por ejemplo, <strong>en</strong> un sistema de control de tráfico aéreo no se quiere limitar el<br />
número de aviones que el sistema pueda gestionar. No puede ser que el programa<br />
se aborte sólo porque se excede algún número. En un sistema de diseño asistido por<br />
computadora, se están manejando montones de formas, pero únicam<strong>en</strong>te el usuario<br />
determina (<strong>en</strong> tiempo de ejecución) cuantas formas serán necesarias. Una vez apreciemos<br />
estas t<strong>en</strong>d<strong>en</strong>cias, se descubrirán montones de ejemplos <strong>en</strong> otras situaciones<br />
de programación.<br />
Los programadores de C que dep<strong>en</strong>d<strong>en</strong> de la memoria virtual para manejar su<br />
"gestión de memoria" <strong>en</strong>cu<strong>en</strong>tran a m<strong>en</strong>udo como perturbant<strong>en</strong>tes las ideas del new,<br />
delete y de los cont<strong>en</strong>edores de clases. Apar<strong>en</strong>tem<strong>en</strong>te, una práctica <strong>en</strong> C es crear<br />
un <strong>en</strong>orme array global, más grande que cualquier cosa que el programa parezca<br />
necesitar. Para esto no es necesario p<strong>en</strong>sar demasiado (o hay que meterse <strong>en</strong> el uso<br />
de malloc() y free()), pero se produc<strong>en</strong> programas que no se pued<strong>en</strong> portar bi<strong>en</strong><br />
y que escond<strong>en</strong> sutiles errores.<br />
Además, si se crea un <strong>en</strong>orme array global de objetos <strong>en</strong> <strong>C++</strong>, la sobrecarga de los<br />
constructores y de los destructores pued<strong>en</strong> <strong>en</strong>l<strong>en</strong>tecer las cosas de forma significativa.<br />
La aproximación de <strong>C++</strong> funciona mucho mejor: Cuando se necesite un objeto,<br />
se crea con new, y se pone su puntero <strong>en</strong> un cont<strong>en</strong>edor. Más tarde, se saca y se<br />
hace algo con él. De esta forma, sólo se crean los objetos cuando sea necesario. Y<br />
normalm<strong>en</strong>te no se dan todas las condiciones para la inicialización al principio del<br />
programa. new permite esperar hasta que suceda algo <strong>en</strong> el <strong>en</strong>torno para poder crear<br />
el objeto.<br />
Así, <strong>en</strong> la situación más común, se creará un cont<strong>en</strong>edor que almac<strong>en</strong>e los punteros<br />
de algunos objetos de interés. Se crearán esos objetos usando new y se pondrá<br />
el puntero resultante <strong>en</strong> el cont<strong>en</strong>edor (pot<strong>en</strong>cialmete haci<strong>en</strong>do upcasting <strong>en</strong> el<br />
proceso), más tarde el objeto se puede recuperar cuando sea necesario. Esta técnica<br />
produce el tipo de programas más flexible y g<strong>en</strong>eral.<br />
16.2. Un vistazo a las plantillas<br />
Ahora surge un nuevo problema. T<strong>en</strong>emos un IntStack, que maneja <strong>en</strong>teros.<br />
Pero queremos una pila que maneje formas, o flotas de aviones, o plantas o cualquier<br />
otra cosa. Reinv<strong>en</strong>tar el código fu<strong>en</strong>te cada vez no parece una aproximación muy<br />
intelig<strong>en</strong>te con un l<strong>en</strong>guaje que propugna la reutilización. Debe haber un camino<br />
mejor.<br />
Hay tres técnicas para reutilizar código <strong>en</strong> esta situación: el modo de C, pres<strong>en</strong>-<br />
481<br />
✐<br />
✐<br />
✐<br />
✐