イテレータ
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 72/104。
イテレータは、コンテナとアルゴリズムの間の架け橋として機能するオブジェクトです。これらは、コンテナが内部でどのようにデータを保持しているかに関わらず、あらゆるコンテナ内の要素にアクセスするための統一された方法を提供します。イテレータは、コンテナ内を移動する方法を知っている汎用化されたポインタであると考えてください。
すべてのSTLコンテナはbegin()メソッドとend()メソッドを提供しています。begin()イテレータは最初の要素を指し、end()は最後の要素の次、つまり停止位置を示す番兵(センチネル)を指します:
#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 << " "; // デリファレンスして値を取得する
}
// 出力: 10 20 30
}autoキーワードは、イテレータの宣言を大幅に簡素化します:
for (auto it = nums.begin(); it != nums.end(); ++it) {
*it *= 2; // イテレータを介して要素を変更する
}
// nums は現在 {20, 40, 60} ですイテレータは、その機能に基づいてさまざまなカテゴリに分類されます。ランダムアクセスイテレータ(vectorのものなど)は、it + 3やit1 - it2などの算術演算をサポートしています。
双方向イテレータ (list, map など) は、++ と -- を使用して前方および後方に移動できます。前方向イテレータは、一方向にのみ移動できます。
逆方向に走査するには、rbegin() と rend() を使用します:
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
std::cout << *rit << " "; // 逆順に出力します
}チャレンジ
簡単イテレータを使用してアイテムのコレクションを走査および操作する、在庫追跡システムを構築しましょう。さまざまな種類のイテレータを使用して、さまざまな方法でデータをナビゲートする練習をします。
コードは2つのファイルに分けて構成します:
Inventory.h:std::vector<int>に格納されたアイテム数量のコレクションを管理するInventoryクラスを定義します。クラスには以下のメソッドを用意する必要があります:
addItem(int quantity)— 在庫にアイテムの数量を追加しますprintForward()—begin()とend()を持つイテレータを使用して、すべての数量をスペースで区切って表示し、最後に改行を出力しますprintReverse()—rbegin()とrend()を持つリバースイテレータを使用して、すべての数量を逆順にスペースで区切って表示し、最後に改行を出力しますdoubleAll()— イテレータを使用してベクトルを走査し、各数量をその場で2倍にしますgetTotal()— イテレータを使用して、すべての数量の合計を計算して返します
コードを簡潔に保つために、イテレータの宣言には
autoキーワードを使用してください。main.cpp: アイテムの数量を表す4つの整数入力(それぞれ別の行)を読み取ります。Inventoryオブジェクトを作成し、4つの数量すべてを追加します。次に、以下を行ってイテレータの使用例を示します:Forward:と出力し、続いてprintForward()を呼び出すReverse:と出力し、続いてprintReverse()を呼び出すgetTotal()を使用してTotal: <sum>と出力するdoubleAll()を呼び出して数量を修正するAfter doubling:と出力し、続いてprintForward()を呼び出すgetTotal()を使用してNew total: <sum>と出力する
例えば、入力が 10、25、15、30 の場合、出力は以下のようになります:
Forward: 10 25 15 30
Reverse: 30 15 25 10
Total: 80
After doubling: 20 50 30 60
New total: 160このチャレンジでは、イテレータを介した要素の読み取り(表示と合計の算出)と、イテレータを介した要素の修正(2倍にする処理)の両方を練習できます。また、リバースイテレータを使用することで、インデックス操作を行うことなく、いかに簡単に逆方向の走査ができるかを確認できます。
チートシート
イテレータは、コンテナ内の要素にアクセスするための統一された方法を提供するオブジェクトです。これらは、コンテナ内を移動する方法を知っている汎用的なポインタとして機能します。
すべてのSTLコンテナは、begin()メソッドとend()メソッドを提供します。begin()イテレータは最初の要素を指し、end()は最後の要素の次を指します。
std::vector<int> nums = {10, 20, 30};
for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
std::cout << *it << " "; // デリファレンスして値を取得する
}autoキーワードを使用して、イテレータの宣言を簡略化します。
for (auto it = nums.begin(); it != nums.end(); ++it) {
*it *= 2; // イテレータを介して要素を修正する
}機能に基づいたイテレータのカテゴリ:
- ランダムアクセスイテレータ(例:
vector)は、it + 3やit1 - it2のような算術演算をサポートします。 - 双方向イテレータ(例:
list、map)は、++と--を使用して前後方向に移動できます。 - 前方イテレータは、一方向にのみ移動できます。
逆方向の走査には、rbegin()とrend()を使用します。
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
std::cout << *rit << " "; // 逆順に表示する
}自分で試してみよう
#include <iostream>
#include "Inventory.h"
using namespace std;
int main() {
// 4つの整数の入力を読み込む
int q1, q2, q3, q4;
cin >> q1;
cin >> q2;
cin >> q3;
cin >> q4;
// TODO: Inventory オブジェクトを作成する
// TODO: 4つの数量すべてを在庫(inventory)に追加する
// TODO: "Forward: " と出力し、その後に printForward() を呼び出す
// TODO: "Reverse: " と出力し、その後に printReverse() を呼び出す
// TODO: "Total: " と出力し、その後に getTotal() の結果を出力する
// TODO: doubleAll() を呼び出して数量を変更する
// TODO: "After doubling: " と出力し、その後に printForward() を呼び出す
// TODO: "New total: " と出力し、その後に getTotal() の結果を出力する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタ引数付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ詳解Rule of Three / Five / Zeroまとめ - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () 演算子のオーバーロード型変換演算子まとめ:Matrix クラス