参考
1. Iteratorパターン 1
デザインパターン「Iterator」
【C++】Iteratorパターンを実装する
まず Iteratorパターン とは
日本語に訳すと「反復子」つまり「繰り返す」という意味になる。
Iteratorパターンの基本的な機能は
要素の集まりを保有するオブジェクトの各要素に順番にアクセスする方法を提供するためのパターンです。
クラス図

画像はShohei Yokoyama様のデザインパターン「Iterator」から引用しています。
クラス図の説明
上記のクラス図は
・抽象クラス
・具像クラス
の2つに大きく分けることができる
抽象クラスの大まかな処理
・抽象クラスでは主に具象クラスで必ず使用する必要のあるクラスを仮想関数・純粋仮想関数で定義する.
この中身は,ほとんどのプロジェクトで同じなので一度その処理内容を覚えるとok
具像クラスの大まかな処理
・抽象クラスを継承し
・順番にアクセスさせたい
・overrideした仮想関数・純粋仮想関数の中身を設定
各クラスの役割
Aggregate
・Iteratorを作成する機能
Iterator
・オブジェクトに順番にアクセスするための機能
・次のオブジェクトが存在しているかのチェックする機能
ConcreteAggregate
・Aggregateを継承してその機能を実装する役割
ConcreteIteretor
・Iteratorを継承してその機能を実装する役割
・このクラスの下にある要素単体のクラスを束ねる
sorce
Aggregate
#pragma once
#include <iostream>
class Iterator;
class Aggregate
{
public:
virtual Iterator* iterator() = 0;
virtual ~Aggregate() {};
};
Iterator
#pragma once
#include<string>
#include<vector>
using namespace std;
class Student;
class Iterator
{
public:
Iterator() {};
virtual ~Iterator() {};
virtual bool HasNext()=0;
virtual Student Next()=0;
};
ConcreteAggregate
#pragma once
#include "Aggregate.h"
#include <iostream>
class Student;
class Iterator;
class StudentList :public Aggregate
{
private:
Student* students;
int last;
public:
StudentList(const int MaxSize);
virtual ~StudentList();
Student const GetStudentAt(int index);
void Add(Student student);
int const GetLength();
Iterator* iterator()override;
};
#include "StudentList.h"
#include "Student.h"
#include "StudentListIterator.h"
StudentList::StudentList(const int MaxSize):last(0)
{
students = new Student[MaxSize];
}
StudentList::~StudentList()
{
delete[] students;
};
Student const StudentList::GetStudentAt(int index)
{
return this->students[index];
}
void StudentList::Add(Student student)
{
this->students[last] = student;
last++;
}
int const StudentList::GetLength()
{
return last;
}
Iterator* StudentList::iterator()
{
return new StudentListIterator(this);
}
ConcreteIteretor
#pragma once
#include "Iterator.h"
class StudentListIterator :public Iterator
{
private:
StudentList* studentList;
int index = 0;
public:
StudentListIterator(StudentList* studentList)
{
this->studentList = studentList;
}
virtual ~StudentListIterator() {};
bool HasNext()override
{
if (index < studentList->GetLength()) return true;
return false;
}
Student Next()override
{
Student student = studentList->GetStudentAt(index);
index++;
return student;
}
};
#pragma once
#include<string>
using namespace std;
class Student
{
private:
string Name;
string Sex;
public:
Student() :Name("") {}
Student(const string name, const string sex)
{
this->Name = name;
this->Sex = sex;
}
virtual ~Student() {};
string const GetName() { return Name; }
string const GetSex() { return Sex; }
void SetName(const string name) { this->Name = name; }
void SetSex(const string Sex) { this->Sex = Sex; }
};
main
#include <iostream>
#include "Student.h"
#include "StudentList.h"
#include "StudentListIterator.h"
using namespace std;
int main() {
StudentList studentList(4);
Student student;
student.SetName("aaa");
student.SetSex("otoko");
studentList.Add(student);
student.SetName("bbb");
student.SetSex("onna");
studentList.Add(student);
student.SetName("ccc");
student.SetSex("otoko");
studentList.Add(student);
student.SetName("ddd");
student.SetSex("onna");
studentList.Add(student);
Iterator* it = studentList.iterator();
while (it->HasNext()) {
Student student = it->Next();
cout << student.GetName() << " " << student.GetSex() << endl;
}
delete it;
return 0;
}
終わりに
C++ではコンテナが,あるので実際はあまり使わないパターンかもしれないが
古いコードを読むことが,絶対にあるのでその時に必要になると思う.