이터레이터는 '원소를 순서대로 접근하는 반복 오브젝트' 정도로 이해하면 되겠다.
'순서'는 거꾸로 혹은 임의의 방식으로 돌아갈 수 있다.
우리는 가장 기본적인 '처음부터 마지막'순서의 이터레이터만 구현해보자
template <typename Data>
class MyVector : public Container_Master<Data>
{
public:
class iterator
{
private:
Data* pos = nullptr;
public:
iterator(Data* pos = 0)
{
this->pos = pos;
}
Data& operator* ()const
{
return *pos;
}
bool operator!=(const iterator& iter)const
{
return pos != iter.pos;
}
bool operator==(const iterator& iter)const
{
return pos == iter.pos;
}
//전위
iterator& operator++()
{
++pos;
return (*this);
}
};
public:
iterator begin()
{
iterator iter(this->my_base);
return iter;
}
iterator end()
{
iterator iter(this->my_base + this->my_size);
return iter;
}
};
나는 벡터클래스 내부에 이터레이터클래스를 생성했다.
따로 이터레이터클래스를 만들어도 되는데 이터레이터는 이정도만 구현해도 될거같아서 그랬다.
코드에서 나오지만 이터레이터는 '원소를 가리키는 포인터'정도로 이해하면 된다.
포인터는 +1을 하면 포인터의 크기만큼 메모리상에서 이동하게 되는데
포인터의 크기는 곧 주소의 크기고 32비트 환경에서는 4바이트, 64비트 환경에서는 8바이트의 사이즈를 가지게 된다.
빈공간없이 붙어있는 벡터의 경우
begin()를 보면 벡터 내부의 배열을 이터레이터생성자로 넘기면
배열의 첫 부분을 가리키는 포인터를 이터레이터가 가지게 된다.
거기서 ++iter를 하게 된다면, 이터레이터 내부의 포인터도 ++pos을 하게 되고,
포인터의 크기만큼 이동하게 되므로 당연히 다음 포인터를 가리키게 되고
그 결과 이터레이터는 다음 원소를 가리키게 된다.
이런 방식이라고 보면된다.
이터레이터로 루프돌리는 방법은
for (MyVector<int>::iterator it = my_vector.begin(); it != my_vector.end(); ++it)
{
cout << (*it) << endl;
}
for (auto it = my_vector.begin(); it != my_vector.end(); ++it)
{
cout << (*it) << endl;
}
for (auto it : vector)
{
cout << (it) << endl;
}
MyVector<int>::iterator를 직접 선언해서 사용해도 되지만 상당히 귀찮기 때문에
c++11이후로 변경된 'auto'키워드를 사용하서 간편하게 다뤄도 된다
range-based for loop방식을 사용하면 더 간편하게 사용할 수 있다.
이 방법도 c++11에서 생긴 방법이다
이제 거의 모든 기능을 구현했지만 하나의 기능을 아직 구현하지 않았다.
그것은 벡터의 원소에 빠르게 접근하기 위한 operator[]
Data& operator[] (const size_t index)
{
//인덱스가 유효하면 인덱스 위치에 보관한 자료를 반환하세요.
this->CheckValidIndex(index);
//데이터를 반환합니다
//반환 형식이 참조 형식임을 주의하세요.
return this->my_base[index];
}
어렵지 않다. 벡터에 []을 사용하면 내부에서 배열에 []을 사용해서 원소를 가져오는 방법이다.
인덱스가 유효한지 검사하는 함수만 추가되었을 뿐이다.
이렇게 벡터의 기본적인 함수를 구현했다.
예제코드에 있지만 여기선 설명하지 않은 함수가 있다. 어려운 코드가 아니니 금방 이해하실 수 있다.
https://github.com/ForestBird1/MyContainer
GitHub - ForestBird1/MyContainer
Contribute to ForestBird1/MyContainer development by creating an account on GitHub.
github.com
'C++ 자료구조' 카테고리의 다른 글
[C++] 나만의 Stack만들기 (2) - Push,Pop,Top 함수 구현 (0) | 2023.08.25 |
---|---|
[C++] 나만의 Stack만들기 (1) - 기초설명 (0) | 2023.08.25 |
[C++] 나만의 Vector만들기 (3) - 원소 삽입, 삭제 (0) | 2023.08.25 |
[C++] 나만의 Vector만들기 (2) - 생성자, 소멸자, 캐퍼시티, Reserve (0) | 2023.08.24 |
[C++] 나만의 Vector만들기 (1) - 기초설명 (0) | 2023.08.24 |