Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO Pensar en C++ (Volumen 1) - Grupo ARCO
✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 480 — #518 ✐ Capítulo 16. Introducción a las Plantillas require(top < ssize, "Too many push()es"); stack[top++] = i; } int pop() { require(top > 0, "Too many pop()s"); return stack[--top]; } }; int main() { IntStack is; // Add some Fibonacci numbers, for interest: for(int i = 0; i < 20; i++) is.push(fibonacci(i)); // Pop & print them: for(int k = 0; k < 20; k++) cout
✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 481 — #519 ✐ 16.2. Un vistazo a las plantillas Esta es una implementación bastante eficiente, porque nunca se generan los números más de una vez. Se usa un array static de int, y se basa en el hecho de que el compilador inicializará el array estático a cero. El primer bucle for mueve el índice i a la primera posición del array que sea cero, entonces un bucle while añade números Fibonacci al array hasta que se alcance el elemento deseado. Hay que hacer notar que si los números Fibonacci hasta el elemento n ya están inicializados, entonces también se salta el bucle while. 16.1.1. La necesidad de los contenedores Obviamente, una pila de enteros no es una herramienta crucial. La necesidad real de los contenedores viene cuando se empizan a crear objetos en el montón (heap) usando new y se destruyen con delete. En un problema general de programación no se saben cuantos objetos van a ser necesarios cuando se está escribiendo el programa. Por ejemplo, en un sistema de control de tráfico aéreo no se quiere limitar el número de aviones que el sistema pueda gestionar. No puede ser que el programa se aborte sólo porque se excede algún número. En un sistema de diseño asistido por computadora, se están manejando montones de formas, pero únicamente el usuario determina (en tiempo de ejecución) cuantas formas serán necesarias. Una vez apreciemos estas tendencias, se descubrirán montones de ejemplos en otras situaciones de programación. Los programadores de C que dependen de la memoria virtual para manejar su "gestión de memoria" encuentran a menudo como perturbantentes las ideas del new, delete y de los contenedores de clases. Aparentemente, una práctica en C es crear un enorme array global, más grande que cualquier cosa que el programa parezca necesitar. Para esto no es necesario pensar demasiado (o hay que meterse en el uso de malloc() y free()), pero se producen programas que no se pueden portar bien y que esconden sutiles errores. Además, si se crea un enorme array global de objetos en C++, la sobrecarga de los constructores y de los destructores pueden enlentecer las cosas de forma significativa. La aproximación de C++ funciona mucho mejor: Cuando se necesite un objeto, se crea con new, y se pone su puntero en un contenedor. Más tarde, se saca y se hace algo con él. De esta forma, sólo se crean los objetos cuando sea necesario. Y normalmente no se dan todas las condiciones para la inicialización al principio del programa. new permite esperar hasta que suceda algo en el entorno para poder crear el objeto. Así, en la situación más común, se creará un contenedor que almacene los punteros de algunos objetos de interés. Se crearán esos objetos usando new y se pondrá el puntero resultante en el contenedor (potencialmete haciendo upcasting en el proceso), más tarde el objeto se puede recuperar cuando sea necesario. Esta técnica produce el tipo de programas más flexible y general. 16.2. Un vistazo a las plantillas Ahora surge un nuevo problema. Tenemos un IntStack, que maneja enteros. Pero queremos una pila que maneje formas, o flotas de aviones, o plantas o cualquier otra cosa. Reinventar el código fuente cada vez no parece una aproximación muy inteligente con un lenguaje que propugna la reutilización. Debe haber un camino mejor. Hay tres técnicas para reutilizar código en esta situación: el modo de C, presen- 481 ✐ ✐ ✐ ✐
- Page 467 and 468: ✐ ✐ ✐ “Volumen1” — 2012
- Page 469 and 470: ✐ ✐ ✐ “Volumen1” — 2012
- Page 471 and 472: ✐ ✐ ✐ “Volumen1” — 2012
- Page 473 and 474: ✐ ✐ ✐ “Volumen1” — 2012
- Page 475 and 476: ✐ ✐ ✐ “Volumen1” — 2012
- Page 477 and 478: ✐ ✐ ✐ “Volumen1” — 2012
- Page 479 and 480: ✐ ✐ ✐ “Volumen1” — 2012
- Page 481 and 482: ✐ ✐ ✐ “Volumen1” — 2012
- Page 483 and 484: ✐ ✐ ✐ “Volumen1” — 2012
- Page 485 and 486: ✐ ✐ ✐ “Volumen1” — 2012
- Page 487 and 488: ✐ ✐ ✐ “Volumen1” — 2012
- Page 489 and 490: ✐ ✐ ✐ “Volumen1” — 2012
- Page 491 and 492: ✐ ✐ ✐ “Volumen1” — 2012
- Page 493 and 494: ✐ ✐ ✐ “Volumen1” — 2012
- Page 495 and 496: ✐ ✐ ✐ “Volumen1” — 2012
- Page 497 and 498: ✐ ✐ ✐ “Volumen1” — 2012
- Page 499 and 500: ✐ ✐ ✐ “Volumen1” — 2012
- Page 501 and 502: ✐ ✐ ✐ “Volumen1” — 2012
- Page 503 and 504: ✐ ✐ ✐ “Volumen1” — 2012
- Page 505 and 506: ✐ ✐ ✐ “Volumen1” — 2012
- Page 507 and 508: ✐ ✐ ✐ “Volumen1” — 2012
- Page 509 and 510: ✐ ✐ ✐ “Volumen1” — 2012
- Page 511 and 512: ✐ ✐ ✐ “Volumen1” — 2012
- Page 513 and 514: ✐ ✐ ✐ “Volumen1” — 2012
- Page 515 and 516: ✐ ✐ ✐ “Volumen1” — 2012
- Page 517: ✐ ✐ ✐ “Volumen1” — 2012
- Page 521 and 522: ✐ ✐ ✐ “Volumen1” — 2012
- Page 523 and 524: ✐ ✐ ✐ “Volumen1” — 2012
- Page 525 and 526: ✐ ✐ ✐ “Volumen1” — 2012
- Page 527 and 528: ✐ ✐ ✐ “Volumen1” — 2012
- Page 529 and 530: ✐ ✐ ✐ “Volumen1” — 2012
- Page 531 and 532: ✐ ✐ ✐ “Volumen1” — 2012
- Page 533 and 534: ✐ ✐ ✐ “Volumen1” — 2012
- Page 535 and 536: ✐ ✐ ✐ “Volumen1” — 2012
- Page 537 and 538: ✐ ✐ ✐ “Volumen1” — 2012
- Page 539 and 540: ✐ ✐ ✐ “Volumen1” — 2012
- Page 541 and 542: ✐ ✐ ✐ “Volumen1” — 2012
- Page 543 and 544: ✐ ✐ ✐ “Volumen1” — 2012
- Page 545 and 546: ✐ ✐ ✐ “Volumen1” — 2012
- Page 547 and 548: ✐ ✐ ✐ “Volumen1” — 2012
- Page 549 and 550: ✐ ✐ ✐ “Volumen1” — 2012
- Page 551 and 552: ✐ ✐ ✐ “Volumen1” — 2012
- Page 553 and 554: ✐ ✐ ✐ “Volumen1” — 2012
- Page 555 and 556: ✐ ✐ ✐ “Volumen1” — 2012
- Page 557 and 558: ✐ ✐ ✐ “Volumen1” — 2012
- Page 559 and 560: ✐ ✐ ✐ “Volumen1” — 2012
- Page 561 and 562: ✐ ✐ ✐ “Volumen1” — 2012
- Page 563 and 564: ✐ ✐ ✐ “Volumen1” — 2012
- Page 565 and 566: ✐ ✐ ✐ “Volumen1” — 2012
- Page 567 and 568: ✐ ✐ ✐ “Volumen1” — 2012
✐<br />
✐<br />
✐<br />
“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 480 — #518<br />
✐<br />
Capítulo 16. Introducción a las Plantillas<br />
require(top < ssize, "Too many push()es");<br />
stack[top++] = i;<br />
}<br />
int pop() {<br />
require(top > 0, "Too many pop()s");<br />
return stack[--top];<br />
}<br />
};<br />
int main() {<br />
IntStack is;<br />
// Add some Fibonacci numbers, for interest:<br />
for(int i = 0; i < 20; i++)<br />
is.push(fibonacci(i));<br />
// Pop & print them:<br />
for(int k = 0; k < 20; k++)<br />
cout