본문 바로가기
C++/기초

C++ 기초 : iterator (4)

글: 시플마 2024. 4. 22.

iterator에 ++ 연산자를 할 수 있도록

연산자 오버로딩을 하겠습니다. 전위 기준으로 작성하겠습니다.

 

일단 예외 처리부터 하였습니다.

 

52번째 줄은 가변 배열에 데이터가 존재하지 않거나,

또는 가변 배열이 새로운 공간에 할당되면서 기존의 공간이

사라졌을 때 오류를 출력하도록 되어 있습니다.

 

가변 배열에 데이터가 없을 때 iterator의 멤버 idx의 값을 -1로 

하였고 vector가 갖고 있는 가변 배열의 시작 주솟값과

iterator가 갖고 있는 가변 배열의 시작 주솟값이 다른 

경우 오류를 출력한다고 볼 수 있네요.

 

 

56번째 줄은

vector의 iCount 값을 반환하는 size 함수를 이용한 것인데요.

iCount는 가변 배열 속 데이터의 개수를 나타냅니다.

해당 개수에서 -1한 값과 iterator의 idx 값이 같다면 idx에 -1을 대입합니다.

 

만약 데이터의 개수가 3개라면, 여기에 -1한 값인 2와 

idx의 값이 2라서 같다면 현재 iterator는 마지막 데이터를

가리키고 있다는 의미겠죠?

 

 

두 if 문에 걸리지 않았다면 

뒤에 데이터가 더 존재한다는 의미이므로

접근이 가능하기 때문에 idx에 1을 더하여

다음 데이터에 접근합니다.

 

 

이후 iterator가 가리키는 값(*this)이 있는 공간 자체를 반환(&iterator)합니다.

 

 

 


 

 

 

이제 for 문과 ++ 연산을 이용하여

 

가변 배열에 하나씩 접근하여 값을 출력하겠습니다.

 

myiter를 하나씩 올려 for 문을 돌릴 건데

myiter는 이미 초기화를 진행했기 때문에

for 문의 초기화 구문을 적지 않아도 됩니다.

 

for 문을 언제까지 반복할 것이냐면

가변 배열에서 마지막 데이터가 있는 부분의

다음 공간(end 함수)과 myiter가 가리키는 공간이

다르면 계속 반복합니다.

 

myiter의 값을 하나씩 올리면서 말이죠.

 

myiter가 가리키는 공간이 end 함수가 반환하는

공간과 같아지면 for 문을 빠져 나갑니다.

 

 

하지만 비교 연산자를 오버로딩하지 않았기 

때문에 위 코드가 작동하지 않을 겁니다.

 

비교 연산자도 오버로딩해야 합니다.

 

먼저 == 연산자부터 보시죠.

 

비교 연산자는 true와 false를 반환하므로

반환 타입을 bool로 하였습니다.

 

비교 연산 오른쪽에 위치하는 iterator를 

인자로 받게 됩니다. 인자로 받는 iterator를 

레퍼런스로 참조하여 복사에 들어가는 비용을 절약합니다.

 

그리고 단순히 비교만 하면 되므로 iterator의 값이

수정되는 것을 방지하기 위해 const 키워드를 붙입니다.

 

 

두 iterator가 같다고 보려면 정확히 같은 곳을

가리키고 있어야 하겠죠?

 

가변 배열에서는 같은 가변 배열을 가리키고 있어야 하며

그 중 같은 인덱스를 가리키고 있어야 같은 iterator라고

볼 수 있겠네요.

 

따라서 가변 배열의 시작 주솟값을 저장하는 m_pData의 값이

같고 동시에 가리키고 있는 인덱스의 번호를 나타내는 idx 값이

같은 경우, == 연산 시 true라고 볼 수 있습니다.

 

해당 경우가 아니면 false를 반환하면 되겠죠.

 

 

다음은 != 연산입니다.

== 연산과 반대로 반환하면 됩니다.

!= 연산 같은 경우 서로 다르면 true, 

같으면 false를 반환하면 되죠.

 

여기서 != 연산을 더 줄여서 표현하면

 

위 코드와 같습니다.

 

!= 연산을 호출한 iterator, 즉 왼쪽 iterator와

인자로 받은 iterator, 즉 오른쪽 iterator에 대해 == 연산을 

진행하고 이 결과를 ! 연산을 하여 반대로 반환하는 겁니다.

 

두 iterator가 같다면 == 연산을 통해 true가 반환될 것이고

이를 다시 ! 연산을 하여 false로 반환함으로써

!= 연산을 하는 것과 같은 결과를 얻는 것이죠.

 

 

이렇게 하면 좋은 점은 == 연산에서

더 다양한 조건이 추가되었다고 가정했을 때,

!= 연산자 오버로딩 코드는 수정할 필요가 없습니다.

 

== 연산 코드만 조건을 더 넣어서 수정해 주고

이 결과를 반대로만 반환하면 != 연산의 역할을

다하는 것이니까요.

 

 

비교 연산자 오버로딩까지 한 후 

 

실행해 보니 가변 배열을 하나씩 순회하면서

저장된 데이터를 잘 출력하는 것을 볼 수 있습니다.

 

 


 

 

 

전위 ++ 연산자를 오버로딩하였으니 

이제는 후위 ++ 연산자를 오버로딩하겠습니다.

 

67번째 줄에서 보이는 코드가

후위 ++ 연산자를 오버로딩한 것입니다.

 

 

전위와 후위 연산의 차이는 연산자가 실행되는 타이밍이죠.

 

int a = 0;

int b = 0;

 

a = b++;

 

위와 같은 코드가 있을 때,

후위 연산이므로 식의 가장 마지막에 실행됩니다.

 

a = b가 먼저 실행이 되고

이후에 b++이 실행되죠.

 

 

반면 전위 ++ 연산이었다면

b의 값을 먼저 올리고 그 값을

a에 대입했을 겁니다.

 

 

하지만 우리가 연산자 오버로딩을 통해

위 예시처럼 연산이 실행되는 타이밍을

조절할 수는 없습니다. 그래서 마치 후위 연산'처럼'

작동하게 구현을 해야 하는 것이죠.

 

 

반환 타입이 iterator형 레퍼런스가 아니고 

그냥 iterator형인 이유는 레퍼런스로 하게 되면

중괄호 안 코드가 실행된 이후 바로 iterator에 

반영되기 때문에 절대 후위 연산처럼 작동할 수 없습니다.

 

 

매개 변수 자리에 int를 쓴 이유는

이름을 넣을 필요 없이 자료형만 넣어 주면 

컴파일러가 알아서 후위 연산자임을 인지하기 때문입니다.

 

 

반환값은 아래 예시를 위해서 임시로 넣었습니다.

 

iterator인 myiter에 ++ 연산을 후위로 적용하였더니

 

 

 

 

자료형을 인자로 받는

++ 연산자 오버로딩 코드를

실행하는 것을 확인할 수 있습니다.

 

 

 

 

 

강의 출처 : https://www.youtube.com/watch?v=PFc4g8mxOiI&list=PL4SIC1d_ab-aOxWPucn31NHkQvNPHK1D1&pp=iAQB


 

'C++ > 기초' 카테고리의 다른 글

C++ 기초 : erase (1)  (0) 2024.04.24
C++ 기초 : iterator (5)  (0) 2024.04.22
C++ 기초 : iterator (3)  (0) 2024.04.22
C++ 기초 : iterator (2)  (0) 2024.04.20
C++ 기초 : iterator (1)  (0) 2024.04.20