[알고리즘/개념/C++] 반복자(iterator)와 STL (Feat. 반복자는 포인터일 뿐이다!)

SHark·2023년 3월 9일
0

알고리즘

목록 보기
10/20

제목은 항상 거창하게 짓지만 , 중간에 틀린부분이 분명히 있을 수 있습니다! 날카로운 피드백은 언제나 환영합니다.

C++에서 Iterator

함수형 프로그램을 하거나 , 객체지향적(OOP)를 했다면 이터레이터라는 말은 사실 낯선용어가 아니다.하지만, 한번도 제대로 공부해보거나 정의를 생각하지 않은체 사용하기만 했다. C++를 사용하면서 Iterator가 없어지는 현상(Iterator 무효) 때문에 Iterator에 대해서 더 자세하게 알아보고, 정리해보고자 한다.

Iterator

항상 무엇인가를 조사할 때는 정의부터 보는 편입니다. 구글에 검색하니, 위키백과에 아래와 같이 안내되어있습니다.

정의만 봐서는 확 닿지는 않지만 , 내부요소를 순환하는 녀석.. 반복하는 친구구만!

Iterater가 왜 생겼을까

컴퓨터 세상에는 사실 아주 훌륭하고 많이 쓰는 for이라는 친구가 있다. 그리고, Iterator가 꼭 필요할까?라고 물어본다면 아니다. 하지만, 매우 번거롭게 될것이다. 다양한 자료구조가 생겨나면서 , 특히 비선형적인 자료구조들은 기존의 선형정인 자료구조와 접근하는 방식이 꽤 달랐다. 자료구조를 단순히 활용하고 싶은 사람 에게 접근을 하기위한 로직을 매번 구현하라고하면, 자신의 비즈니스 로직에 집중을 하지 못할 수 있다.(그림을 그리고 싶은데, 물감이 없어서 염료를 직접 추출하기 위해 꽃을 키우는 격)

즉, 내가 말하고 싶은 점은 iterator는 반복을 쉽게하기 위해서 만든 일종의 편의장치일 뿐이란걸 강조하고 싶다. 자료구조에대한 접근방법을 추상화 시킨 객체이다. Iterator가 없다면, STL에 있는 자료구조들은 각자 메모리 내에 구현되어있는 방식이 다르기 때문에, 자료구조마다 내부요소에 접근하는 방법이 달라지게된다.

Iterator는 복잡한 접근을 쉽게해준다.

정리하자면, C++에서 Iterator는 어떤 자료구조를 접근하든 동일한 방법으로 접근하게끔 만들어주는 객체이다.특히, 메모리 주소값을 갖는 객체이다. 머리를 가볍게 하기 위해서, 메모리 주소값을 갖고 있는 반복에 도움이 되는 객체라고 생각하면 된다.

Iterator는 여러가지가 있다.

사실, 우리가 배열에서 쓰고 있는 []이 친구도 이터레이터 중 하나이다. 배열이라는 구조에서 특정 요소에 접근을 하기 위해서 연산을 하기 때문이다. 시작주소 + 대괄호 안에 있는 값을 통해 배열의 요소에 접근하게된다. 벡터도 배열 기반으로 자료구조가 형성되었기 때문에 , 랜덤엑세스 이터레이터도 통한다. 이 외에도 다양한 이터레이터가 있지만 글의 내용을 헤칠 수 있기 때문에 아래링크를 참고하자.

https://cplusplus.com/reference/iterator/iterator/?kw=iterator

자료구조별로 다른 특징이 나타난다.

Iterator는 포인터이다. STL의 주소값을 가지므로, 여기서 리스트(연결리스트),벡터 등과 같은 각각의 STL의 이터레이터가 다르게 동작하는 것처럼 느껴지는 포인트이다. Vector과 List(이중연결리스트)를 비교해보자.

이때, 이터레이터가 가리키는 곳의 요소가 삭제된다면 어떻게 될까? 배열은 뒤에서 밀어서 앞으로 넣을거고 , 연결리스트는 주소값만 바꿔주면된다.

vector<int> v = { 1,2,3,4,5 };
 
vector<int>::iterator iter = v.begin(); //시작점
iter++;
 
v.erase(iter);
cout << *iter << '\n'; // 반복자 무효화

이때, iterator가 가리키는 주소 또한 삭제가 되므로, erase와 같은 삭제 연산을 한 뒤에는 iterator를 재할당 해주어야한다.

vector<int> v = { 1,2,3,4,5 };
 
vector<int>::iterator iter = v.begin(); //시작점
iter++;
 
iter= v.erase(iter);
cout << *iter << '\n'; // 반복자 무효화

연결리스트도 삭제는 마찬가지이다.,삭제같은 경우에는 두가지 자료형 모두 이터레이터를 재할당해줘야한다 하지만 ,삽입 과정에서 차이가 나게된다.

vector vs List 삽입과정

vector은 메모리의 연속적인 공간에 잇으므로 , 삽입하면 삽입한 자료 뒤로 다 한칸씩 밀리게 되므로 메모리 주소가 다 바뀌게 되므로, 이터레이터가 무효화가 된다. 하지만, 연결리스트같은 경우에는 애초에 메모리 공간에 따로 존재하므로 기존 iterator가 무효가 되지않는다.

0개의 댓글