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

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

Saved successfully!

Ooh no, something went wrong!