Iteradores
Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy. Lección 72 de 104.
Los iteradores son objetos que actúan como puente entre los contenedores y los algoritmos. Proporcionan una forma uniforme de acceder a los elementos de cualquier contenedor, independientemente de cómo almacene sus datos internamente. Piensa en un iterador como un puntero generalizado que sabe cómo desplazarse por un contenedor.
Todos los contenedores de STL proporcionan los métodos begin() y end(). El iterador begin() apunta al primer elemento, mientras que end() apunta a la posición siguiente al último elemento: un centinela que marca dónde detenerse:
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums = {10, 20, 30};
for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
std::cout << *it << " "; // Desreferencia para obtener el valor
}
// Salida: 10 20 30
}La palabra clave auto simplifica significativamente las declaraciones de iteradores:
for (auto it = nums.begin(); it != nums.end(); ++it) {
*it *= 2; // Modifica los elementos mediante el iterador
}
// nums ahora es {20, 40, 60}Los iteradores se dividen en distintas categorías según sus capacidades. Los iteradores de acceso aleatorio (como los de vector) admiten operaciones aritméticas como it + 3 o it1 - it2.
Los iteradores bidireccionales (de list, map) pueden avanzar y retroceder con ++ y --. Los iteradores hacia delante solo pueden avanzar en una dirección.
Para recorrer en orden inverso, usa rbegin() y rend():
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
std::cout << *rit << " "; // Imprime en orden inverso
}Desafío
FácilConstruyamos un sistema de seguimiento de inventario que use iteradores para recorrer y manipular colecciones de artículos. Practicarás el uso de distintos tipos de iteradores para navegar por los datos de varias maneras.
Organizarás tu código en dos archivos:
Inventory.h: Define una claseInventoryque administre una colección de cantidades de artículos almacenadas en unstd::vector<int>.Tu clase debe proporcionar estos métodos:
addItem(int quantity): agrega una cantidad de artículos al inventarioprintForward(): usa iteradores conbegin()yend()para imprimir todas las cantidades separadas por espacios, seguidas de un salto de líneaprintReverse(): usa iteradores inversos conrbegin()yrend()para imprimir todas las cantidades en orden inverso, separadas por espacios, seguidas de un salto de líneadoubleAll(): usa iteradores para recorrer el vector y duplicar cada cantidad en su lugargetTotal(): usa iteradores para calcular y devolver la suma de todas las cantidades
Usa la palabra clave
autoen las declaraciones de tus iteradores para mantener el código limpio.main.cpp: Lee cuatro valores enteros (cada uno en una línea distinta) que representen las cantidades de artículos.Crea un objeto
Inventoryy agrega las cuatro cantidades. Luego, demuestra el uso de iteradores:- Imprime
Forward:y luego llama aprintForward() - Imprime
Reverse:y luego llama aprintReverse() - Imprime
Total: <sum>usandogetTotal() - Llama a
doubleAll()para modificar las cantidades - Imprime
After doubling:y luego llama aprintForward() - Imprime
New total: <sum>usandogetTotal()
- Imprime
Por ejemplo, con las entradas 10, 25, 15 y 30:
Forward: 10 25 15 30
Reverse: 30 15 25 10
Total: 80
After doubling: 20 50 30 60
New total: 160Este desafío te permite practicar tanto la lectura de elementos mediante iteradores (para imprimir y sumar) como la modificación de elementos mediante iteradores (para duplicar). También verás cómo los iteradores inversos facilitan el recorrido hacia atrás sin manipular índices.
Pruébalo tú mismo
#include <iostream>
#include "Inventory.h"
using namespace std;
int main() {
// Lee cuatro números enteros de entrada
int q1, q2, q3, q4;
cin >> q1;
cin >> q2;
cin >> q3;
cin >> q4;
// TODO: Crea un objeto Inventory
// TODO: Añade las cuatro cantidades al inventario
// TODO: Imprime "Forward: " y luego llama a printForward()
// TODO: Imprime "Reverse: " y luego llama a printReverse()
// TODO: Imprime "Total: " seguido del resultado de getTotal()
// TODO: Llama a doubleAll() para modificar las cantidades
// TODO: Imprime "After doubling: " y luego llama a printForward()
// TODO: Imprime "New total: " seguido del resultado de getTotal()
return 0;
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de la POO
Archivos externosCompilación y construcción en C++Archivos de cabecera y archivos fuenteEspacios de nombres y ámbitoIntroducción a la POO en C++Clases y objetosEl puntero 'this'Métodos (funciones miembro)Atributos (miembros de datos)Fundamentos de constructores y destructoresRepaso: calculadora sencilla4Propiedades de clase
Miembros de instancia vs. estáticosGetters y settersFunciones miembro constPalabra clave mutableMétodos y variables estáticosFunciones y clases friendRepaso: gestor de cuentas bancarias7Herencia
Herencia básicaNiveles de acceso en la herenciaOrden de llamada de constructores y destructoresSobrescritura de métodosFunciones virtuales y VTableHerencia múltipleHerencia virtualRepaso: jerarquía de empleados10Visión general de STL
Visión general y filosofía de STLContenedores de STLIteradoresAlgoritmos de STLFunctores y expresiones lambdaRepaso: frecuencia de palabras2Gestión de memoria
Memoria de pila vs. heapPunteros y referenciasMemoria dinámica (new/delete)Punteros inteligentes en C++RAII en C++Repaso: gestor de arreglos dinámicos5Encapsulación
Especificadores de acceso en C++Especificadores de acceso en profundidadOcultación de informaciónStruct vs. classClases anidadas e internasRepaso: sistema de registros de estudiantes8Polimorfismo
Polimorfismo en compilación y en tiempo de ejecuciónSobrecarga de funcionesRepaso de las funciones virtualesFunciones virtuales purasClases abstractasDiseño de interfaces en C++Conversión dinámica y RTTIRepaso: calculadora de formas11Conceptos avanzados de POO
Composición frente a herenciaMixins mediante CRTPIdiom PimplBorrado de tiposClases enum y tipado fuerteManejo de excepciones en POOJerarquías de excepciones personalizadas14Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositeRAII como patrón3Constructores y destructores
Constructor predeterminadoConstructor con parámetrosConstructor de copiaConstructor de movimientoListas de inicialización del constructorConstructores delegadosAnálisis detallado del destructorRegla de tres / cinco / ceroRepaso: clase String6Sobrecarga de operadores
Introducción a la sobrecarga de operadoresSobrecarga de operadores aritméticosSobrecarga de operadores de comparaciónOperadores de flujoSobrecarga del operador de asignaciónSobrecarga de los operadores [] y ()Operadores de conversión de tipoRepaso: clase Matrix9Plantillas
Plantillas de funcionesPlantillas de clasesEspecialización de plantillasPlantillas variádicasFundamentos de SFINAE y rasgos de tiposRepaso: contenedor genéricoPractica por tu cuenta: Compilador de C++ online