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 un puente entre los contenedores y los algoritmos. Proporcionan una forma uniforme de acceder a los elementos de cualquier contenedor, independientemente de cómo ese contenedor almacene sus datos internamente. Piense en un iterador como un puntero generalizado que sabe cómo moverse a través de un contenedor.
Cada contenedor de la STL proporciona los métodos begin() y end(). El iterador begin() apunta al primer elemento, mientras que end() apunta a una posición después del ú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 << " "; // Desreferenciar 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; // Modificar elementos a través del iterador
}
// nums es ahora {20, 40, 60}Los iteradores se dividen en diferentes 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 moverse hacia adelante y hacia atrás con ++ y --. Los iteradores de avance solo pueden moverse en una dirección.
Para el recorrido inverso, utiliza rbegin() y rend():
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
std::cout << *rit << " "; // Imprime en orden inverso
}Desafío
FácilVamos a construir un sistema de seguimiento de inventario que utiliza iteradores para recorrer y manipular colecciones de artículos. Practicarás el uso de diferentes tipos de iteradores para navegar a través de los datos de varias maneras.
Organizarás tu código en dos archivos:
Inventory.h: Define una claseInventoryque gestiona una colección de cantidades de artículos almacenadas en unstd::vector<int>.Tu clase debe proporcionar estos métodos:
addItem(int quantity)— añade una cantidad de artículo al inventarioprintForward()— utiliza iteradores conbegin()yend()para imprimir todas las cantidades separadas por espacios, seguidas de una nueva líneaprintReverse()— utiliza iteradores inversos conrbegin()yrend()para imprimir todas las cantidades en orden inverso, separadas por espacios, seguidas de una nueva líneadoubleAll()— utiliza iteradores para recorrer el vector y duplicar cada cantidad in situgetTotal()— utiliza iteradores para calcular y devolver la suma de todas las cantidades
Utiliza la palabra clave
autopara las declaraciones de tus iteradores para mantener el código limpio.main.cpp: Lee cuatro entradas enteras (cada una en una línea separada) que representan cantidades de artículos.Crea un
Inventoryy añade las cuatro cantidades. Luego, demuestra el uso de iteradores mediante:- Imprimir
Forward:seguido de la llamada aprintForward() - Imprimir
Reverse:seguido de la llamada aprintReverse() - Imprimir
Total: <sum>usandogetTotal() - Llamar a
doubleAll()para modificar las cantidades - Imprimir
After doubling:seguido de la llamada aprintForward() - Imprimir
New total: <sum>usandogetTotal()
- Imprimir
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 a través de iteradores (para imprimir y sumar) como la modificación de elementos a través de iteradores (para duplicar). También verás cómo los iteradores inversos hacen que el recorrido hacia atrás sea sencillo sin ninguna manipulación de índices.
Hoja de referencia
Los iteradores son objetos que proporcionan una forma uniforme de acceder a los elementos en los contenedores. Actúan como punteros generalizados que saben cómo desplazarse a través de un contenedor.
Cada contenedor de la STL proporciona los métodos begin() y end(). El iterador begin() apunta al primer elemento, mientras que end() apunta a una posición después del último elemento:
std::vector<int> nums = {10, 20, 30};
for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
std::cout << *it << " "; // Desreferenciar para obtener el valor
}Utilice la palabra clave auto para simplificar las declaraciones de los iteradores:
for (auto it = nums.begin(); it != nums.end(); ++it) {
*it *= 2; // Modificar elementos a través del iterador
}Categorías de iteradores basadas en sus capacidades:
- Iteradores de acceso aleatorio (por ejemplo,
vector) admiten operaciones aritméticas comoit + 3oit1 - it2 - Iteradores bidireccionales (por ejemplo,
list,map) pueden moverse hacia adelante y hacia atrás con++y-- - Iteradores hacia adelante solo pueden moverse en una dirección
Para el recorrido inverso, utilice rbegin() y rend():
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
std::cout << *rit << " "; // Imprime en orden inverso
}Pruébalo tú mismo
#include <iostream>
#include "Inventory.h"
using namespace std;
int main() {
// Lee cuatro entradas de enteros
int q1, q2, q3, q4;
cin >> q1;
cin >> q2;
cin >> q3;
cin >> q4;
// TODO: Crea un objeto Inventory
// TODO: Agrega 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 OOP
Archivos externosConstrucción y compilación en C++Archivos de cabecera y archivos fuenteNamespaces y alcanceIntroducción a OOP en C++Clases vs ObjetosEl puntero 'this'Métodos (Funciones miembro)Atributos (Miembros de datos)Conceptos básicos de Ctors y DtorsResumen - Calculadora simple4Propiedades de clase
Miembros de instancia vs. estáticosGetters y SettersFunciones miembro constPalabra clave mutableMétodos y variables estáticosFunciones y clases amigasResumen - Gestor de cuentas bancarias7Herencia
Herencia básicaNiveles de acceso en la herenciaOrden de llamada de Ctor y DtorSobrescritura de métodosFunciones virtuales y VTableHerencia múltipleHerencia virtualResumen - Jerarquía de empleados10Visión general de la STL
Visión general y filosofía de la STLContenedores de la STLIteradoresAlgoritmos de la STLFuntores y expresiones lambdaResumen - Frecuencia de palabras2Gestión de memoria
Memoria Stack vs HeapPunteros y referenciasMemoria dinámica (new/delete)Punteros inteligentes en C++RAII en C++Resumen - Gestor de arrays dinámicos5Encapsulamiento
Especificadores de acceso en C++Especificadores de acceso en profundidadOcultamiento de informaciónStruct vs ClassClases anidadas e internasResumen - Sistema de registros de estudiantes8Polimorfismo
Polimorfismo: Compilación vs. Tiempo de ejecuciónSobrecarga de funcionesFunciones virtuales revisadasFunciones virtuales purasClases abstractasDiseño de interfaces en C++Dynamic Casting y RTTIResumen: Calculadora de figuras11Conceptos avanzados de POO
Composición vs. HerenciaMixins mediante CRTPIdioma PimplBorrado de tiposEnum Classes 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 por defectoConstructor parametrizadoConstructor de copiaConstructor de movimientoListas de inicialización del constructorConstructores delegadosAnálisis profundo del destructorRegla de tres / cinco / ceroResumen - Clase String6Sobrecarga de operadores
Introducción a la sobrecarga de operadoresSobrecarga de operadores aritméticosSobrecarga de operadores de comparaciónOperadores de flujo (Stream)Sobrecarga del operador de asignaciónSobrecarga de los operadores [] y ()Operadores de conversión de tiposResumen - Clase Matrix9Plantillas
Plantillas de funcionesPlantillas de clasesEspecialización de plantillasPlantillas variádicasConceptos básicos de SFINAE y Type TraitsResumen - Contenedor genérico