13.01.2015 Views

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

SHOW MORE
SHOW LESS

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 />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!