Menu
Coddy logo textTech

Iteradores

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 72 de 104.

Iteradores são objetos que atuam como uma ponte entre contêineres e algoritmos. Eles fornecem uma maneira uniforme de acessar elementos em qualquer contêiner, independentemente de como esse contêiner armazena seus dados internamente. Pense em um iterador como um ponteiro generalizado que sabe como percorrer um contêiner.

Todo contêiner STL fornece os métodos begin() e end(). O iterador begin() aponta para o primeiro elemento, enquanto end() aponta para uma posição após o último elemento - uma sentinela que marca onde parar:

#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 obter o valor
    }
    // Saída: 10 20 30
}

A palavra-chave auto simplifica significativamente as declarações de iteradores:

for (auto it = nums.begin(); it != nums.end(); ++it) {
    *it *= 2;  // Modifica elementos através do iterador
}
// nums agora é {20, 40, 60}

Iteradores vêm em diferentes categorias com base em suas capacidades. Iteradores de acesso aleatório (como aqueles de vector) suportam operações aritméticas como it + 3 ou it1 - it2.

Iteradores bidirecionais (de list, map) podem se mover para frente e para trás com ++ e --. Iteradores forward podem se mover apenas em uma direção.

Para percorrer em ordem inversa, use rbegin() e rend():

for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
    std::cout << *rit << " ";  // Imprime na ordem inversa
}
challenge icon

Desafio

Fácil

Vamos construir um sistema de rastreamento de inventário que utiliza iteradores para percorrer e manipular coleções de itens. Você praticará o uso de diferentes tipos de iteradores para navegar pelos dados de várias maneiras.

Você organizará seu código em dois arquivos:

  • Inventory.h: Defina uma classe Inventory que gerencia uma coleção de quantidades de itens armazenadas em um std::vector<int>.

    Sua classe deve fornecer estes métodos:

    • addItem(int quantity) — adiciona uma quantidade de item ao inventário
    • printForward() — usa iteradores com begin() e end() para imprimir todas as quantidades separadas por espaços, seguidas por uma nova linha
    • printReverse() — usa iteradores reversos com rbegin() e rend() para imprimir todas as quantidades em ordem reversa, separadas por espaços, seguidas por uma nova linha
    • doubleAll() — usa iteradores para percorrer o vetor e dobrar cada quantidade no local
    • getTotal() — usa iteradores para calcular e retornar a soma de todas as quantidades

    Use a palavra-chave auto para suas declarações de iteradores para manter o código limpo.

  • main.cpp: Leia quatro entradas inteiras (cada uma em uma linha separada) representando quantidades de itens.

    Crie um Inventory e adicione todas as quatro quantidades. Em seguida, demonstre o uso de iteradores:

    1. Imprimindo Forward: seguido pela chamada de printForward()
    2. Imprimindo Reverse: seguido pela chamada de printReverse()
    3. Imprimindo Total: <sum> usando getTotal()
    4. Chamando doubleAll() para modificar as quantidades
    5. Imprimindo After doubling: seguido pela chamada de printForward()
    6. Imprimindo New total: <sum> usando getTotal()

Por exemplo, com as entradas 10, 25, 15, e 30:

Forward: 10 25 15 30 
Reverse: 30 15 25 10 
Total: 80
After doubling: 20 50 30 60 
New total: 160

Este desafio permite que você pratique tanto a leitura de elementos através de iteradores (para impressão e soma) quanto a modificação de elementos através de iteradores (para dobrar). Você também verá como os iteradores reversos tornam a travessia para trás direta, sem qualquer manipulação de índice.

Folha de consulta

Iteradores são objetos que fornecem uma maneira uniforme de acessar elementos em contêineres. Eles agem como ponteiros generalizados que sabem como se mover através de um contêiner.

Todo contêiner STL fornece os métodos begin() e end(). O iterador begin() aponta para o primeiro elemento, enquanto end() aponta para uma posição após o último elemento:

std::vector<int> nums = {10, 20, 30};

for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
    std::cout << *it << " ";  // Desreferencie para obter o valor
}

Use a palavra-chave auto para simplificar as declarações de iteradores:

for (auto it = nums.begin(); it != nums.end(); ++it) {
    *it *= 2;  // Modifique elementos através do iterador
}

Categorias de iteradores baseadas em capacidades:

  • Iteradores de acesso aleatório (ex: vector) suportam operações aritméticas como it + 3 ou it1 - it2
  • Iteradores bidirecionais (ex: list, map) podem se mover para frente e para trás com ++ e --
  • Iteradores de avanço (Forward iterators) só podem se mover em uma direção

Para travessia reversa, use rbegin() e rend():

for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
    std::cout << *rit << " ";  // Imprime em ordem reversa
}

Experimente você mesmo

#include <iostream>
#include "Inventory.h"

using namespace std;

int main() {
    // Leia quatro entradas inteiras
    int q1, q2, q3, q4;
    cin >> q1;
    cin >> q2;
    cin >> q3;
    cin >> q4;

    // TODO: Crie um objeto Inventory

    // TODO: Adicione todas as quatro quantidades ao inventário

    // TODO: Imprima "Forward: " e então chame printForward()

    // TODO: Imprima "Reverse: " e então chame printReverse()

    // TODO: Imprima "Total: " seguido pelo resultado de getTotal()

    // TODO: Chame doubleAll() para modificar as quantidades

    // TODO: Imprima "After doubling: " e então chame printForward()

    // TODO: Imprima "New total: " seguido pelo resultado de getTotal()

    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos