본문 바로가기

Information Technology/java

iterator


An iterator is an object that can "iterate" (navigate) over elements. - The C++ Standrad Library

 

Iterator는 컨테이너의 원소들을 순회(돌아다니다^^)할 수 있는 객체입니다.

반복자는 컨테이너의 특정 위치를 가리킵니다. 반복자는 Pointer와 같이 연산자를 사용할 수 있는데 pointer와 비슷합니다. 연산자 오버로드 되어있는것이죠.

 

operator *   : 현재 가리키고 있는 위치 값

operator ++ : 다음 원소

operator -- : 이전 원소

operator != , == : 두 반복자가 같은 위치를 가리키고 있는지

operator = : 반복자를 할당합니다.

 

가만히 보면 pointer와 별다른 것이 없어 보입니다. 좀 다르다고 할 수 있는건 복잡한 컨테이너를 순회할 수 있는 스마트포인터라는 것입니다. 나중에 예제로 보겠지만 컨테이너::iterator 로 지정해주면 지정한 컨테이너 타입에 맞춰 움직이다가 iterator 알아서 메모리 관리가 됩니다. 지정한 자료의 삭제 같은 것이 필요 없다는 것이죠.

 

컨테이너에 보면 가지고 있는 원소를 순회하기 위해 공통 멤버 함수가 있습니다. 간단하게

begin() 과 end()을 보도록 하죠.

 

여기꽤 중요한 것이 있는데 end()는 마지막을 하나 지난 위치 입니다. --? 좀 이상하죠 이걸 half-open range(반 개방 범위)라고 하는데요 2가지 장점이 있습니다. 꼭 장점만 있지는 않습니다.. 잘못처리 하면 문제일으킬 소지를 다분히 가지고 있습니다.

 

  1.원소를 순회하는 루프를 간단히 할 수 있다. end()에 다다르지 않았다면 계속해서 루프를 돌면 된다.

  2.빈 범위에 대해서 특별한 처리를 할 필요가 없다. 빈 컨테이너에 대해서 begin()과 end()는 동일하다.

 

이런 특성 때문에 for 문을 작성할 때

for(vector<char>::iterator a = c.begin ; a != c.end() ; ++a)

와 같은 식으로 != 로 비교하고 ++a 를 사용합니다. end() 같지 않을 때 까지 계속 이동하면서 증가를 합니다. 증가 연산은 전위(prefix operator)를 사용합니다. 이유는 class에서 증가연산자를 overloading 해 보셨다면 왜인지 아실것 같은데 후위(postfix)는 반복자의 이전값을 반환하기 때문에 임시로 객체가 생깁니다. 아무래도 전위 증가/감소가 성능이 좋겠죠. 후위를 써도 괜찮긴 하지만 사용하지 마세요. 늦으니까...

 

그리고 iterator은 두 가지가 있는데

container::iterator   원소들을 읽기/쓰기 가능합니다.

container::const_iterator   읽기 전용으로 순회합니다.

 

간단한 예를 볼까요.

 

#include <iostream>

#include <vector>

using namespace std;

 

int main()

{

    vector<int> vnData;

 

    for(int a = 1 ; a <= 10 ; ++a) {

         vnData.push_back(a);                   //push_back() 는 vector에 원소를 삽입합니다.

    }

 

    vector<int>::const_iterator pos;    //vector container의 iterator를 만들고

    for(pos = vnData.begin() ; pos != vnData.end() ; ++pos) {

        cout << *pos << ' ' ;                    // end()까지 반복해서 vnData의 값을 출력합니다.

    }

    cout << endl;

}

 

예제에서 != 연사자를 써서 비교를 하는데요. vector의 경우는 < 연산자 사용이 가능합니다.

이것이 무슨 말인가 하면 컨테이너의 내부 구조에 따라 다른 기능을 할 수 있다라는 것입니다.

컨테이너 중에 random access 가 가능한 것(vector, deque, string class)은 더하고 빼고 <, > 비교할 수 있습니다. 이를 random access iterator 라고 하고,

증가 감소 연산자로 양쪽 방향(앞,뒤)으로 이동할 수 있는 것이 Bidirectional iterator(양방향 반복자)이고 list, set, multiset, map, multimap의 반복자 입니다..

 

for(pos=vnData.begin() ; pos != vnData.end() ; ++pos)

는 모든 컨테이너에 쓸 수 있는 것이지만

for(pos=vnData.begin() ; pos < vnData.end() ; ++pos)

이는 random access 가 가능한 컨테이너 타입에만 적용할 수 있습니다.

 

iterator는 알고 보면 참 신기하게 움지이는 스마트 포인트 객체 입니다.

나중에 iterator adapter 에 대한 것을 언급하게 될것 같은데요. 이 또한 중요하고 효과적인 사용에 도움을 줄것이라 생각합니다.

촐처 : http://cafe.naver.com/cafec.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=994