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 502 — #540<br />
✐<br />
Capítulo 16. Introducción a las Plantillas<br />
El IntStackIter ha sido creado para trabajar solo con un IntStack. Hay<br />
que resaltar que IntStackIter es un fri<strong>en</strong>d de IntStack, lo que lo da un<br />
acceso a todos los elem<strong>en</strong>tos privados de IntStack.<br />
Como un puntero, el trabajo de IntStackIter consiste <strong>en</strong> moverse a través<br />
de un IntStack y devolver valores. En este s<strong>en</strong>cillo ejemplo, el objeto IntStackIter<br />
se puede mover sólo hacia adelante (usando la forma prefija y sufija del<br />
operador++ ). Sin embargo, no hay límites de la forma <strong>en</strong> que se puede definir un<br />
iterador a parte de las restricciones impuestas por el cont<strong>en</strong>edor con el que trabaje.<br />
Esto es totalm<strong>en</strong>te aceptable (incluido los límites del cont<strong>en</strong>edor que se <strong>en</strong>cu<strong>en</strong>tre<br />
por debajo) para un iterador que se mueva de cualquier forma por su cont<strong>en</strong>edor<br />
asociado y para que se puedan modificar los valores del cont<strong>en</strong>edor.<br />
Es usual el que un iterador sea creado con un constructor que lo asocie a un<br />
único objeto cont<strong>en</strong>edor, y que ese iterador no pueda ser asociado a otro cont<strong>en</strong>edor<br />
difer<strong>en</strong>te durante su ciclo de vida. (Los iteradores son normalem<strong>en</strong>te pequeños y<br />
baratos, por lo que se puede crear otro fácilm<strong>en</strong>te).<br />
Con el iterador, se puede atravesar los elem<strong>en</strong>tos de la pila sin sacarlos de ella,<br />
como un puntero se mueve a través de los elem<strong>en</strong>tos del array. Sin embargo, el iterador<br />
conoce la estructura interna de la pila y como atravesar los elem<strong>en</strong>tos, dando<br />
la s<strong>en</strong>sación de que se está movi<strong>en</strong>do a través de ellos como si fuera «increm<strong>en</strong>tar<br />
un puntero», aunque sea más complejo lo que pasa por debajo. Esta es la clave del<br />
iterador: Abstrae el proceso complicado de moverse de un elem<strong>en</strong>to del cont<strong>en</strong>edor<br />
al sigui<strong>en</strong>te y lo convierte <strong>en</strong> algo parecido a un puntero. La meta de cada iterador<br />
del programa es que t<strong>en</strong>gan la misma interfaz para que cualquier código que use un<br />
iterador no se preocupe de a qué está apuntando - sólo se sabe que todos los iteradores<br />
se tratan de la misma manera, por lo que no es importante a lo que apunte<br />
el iterador. De esta forma se puede escribir código más g<strong>en</strong>érico. Todos los cont<strong>en</strong>edores<br />
y algoritmos <strong>en</strong> la Librería Estándar de <strong>C++</strong> se basan <strong>en</strong> este principio de los<br />
iteradores.<br />
Para ayudar a hacer las cosas más g<strong>en</strong>éricas, sería agradable decir «todas las clases<br />
cont<strong>en</strong>edoras ti<strong>en</strong><strong>en</strong> una clase asociada llamada iterator», pero esto causará<br />
normalm<strong>en</strong>te problemas de nombres. La solución consite <strong>en</strong> añadir una clase anidada<br />
para cada cont<strong>en</strong>edor (<strong>en</strong> este caso, «iterator» comi<strong>en</strong>za con una letra minúscula<br />
para que esté conforme al estilo del <strong>C++</strong> estándar). Aquí está el InterIntStack.<br />
cpp con un iterator anidado:<br />
//: C16:NestedIterator.cpp<br />
// Nesting an iterator inside the container<br />
//{L} fibonacci<br />
#include "fibonacci.h"<br />
#include "../require.h"<br />
#include <br />
#include <br />
using namespace std;<br />
class IntStack {<br />
<strong>en</strong>um { ssize = 100 };<br />
int stack[ssize];<br />
int top;<br />
public:<br />
IntStack() : top(0) {}<br />
void push(int i) {<br />
require(top < ssize, "Too many push()es");<br />
stack[top++] = i;<br />
502<br />
✐<br />
✐<br />
✐<br />
✐