이번에는 C++에서 가장 많이 사용하는 vector를 구현해보았다. 완벽하게 똑같이 만들고싶은 욕심이 있었지만 한계가 있었다. 우선 소스코드는 아래 링크에 있다.
https://github.com/Seo-sang/C-_Standard_Template_Library
GitHub - Seo-sang/C-_Standard_Template_Library: make C++ STL myself
make C++ STL myself. Contribute to Seo-sang/C-_Standard_Template_Library development by creating an account on GitHub.
github.com
1. 벡터 동작 방식
벡터는 크기가 부족할 경우 크기를 두 배씩 늘리는 동적배열이다. 따라서 초기 배열의 크기를 10으로 잡았다. 처음 myvector를 선언할 경우 배열의 크기는 10으로 설정된다. push_back을 했을 때 공간이 부족한 경우 길이 2배짜리 배열을 만든 후 원래 배열의 내용을 옮겨 담는다. 반대로 pop_back도 마찬가지이다. 현재 배열을 사용하는 공간이 이전 배열의 1/2보다 작은 경우 배열의 크기를 1/2로 줄이고 내용을 복사한다.
2. iterator
벡터뿐 아니라 다른 STL에서도 iterator 기능은 굉장히 많이 사용한다. 그렇기 때문에 이 기능은 뺄 수 없었다. iterator가할 수 있는 연산은 ++, --, *, !=, == 총 5가지를 구현하였다. iterator를 구현하며 클래스 자체를 리턴할 수 있음을 알 수 있었다. 현재 가리키는 포인터를 하나 두어 상대적인 연산을 하도록 만들었다. iterator class의 코드는 다음과 같다.
class myiterator {
T* current;
public:
myiterator(T* node = 0) : current(node) {};
myiterator& operator++() {
current++;
return *this;
}
myiterator& operator--() {
current--;
return *this;
}
T& operator*() {
return *current;
}
bool operator !=(const myiterator& cmp) {
return (current != cmp.current);
}
bool operator ==(const myiterator& cmp) {
return (current == cmp.current);
}
};
클래스의 멤버 변수는 하나가 있다 current라는 변수로 벡터 배열의 원소를 가리키는 포인터이다. iterator는 항상 begin부터 시작하거나 end부터 시작한다. 그렇기 때문에 begin, end 코드를 보면 다음과 같다.
myiterator begin() {
return myiterator(head);
}
myiterator end() {
return myiterator(tail);
}
생성자를 이용하여 head와 tail을 현재 포인터로 하는 생성자를 만들었다. begin()을 호출할 경우 iterator는 가장 첫 번째 원소를 가리킨다. end()를 호출할 경우 iterator는 가장 마지막원소 다음을 가리킨다. 벡터에서 end에는 원소가 존재하지 않고 마지막을 나타낸다. 그렇기 때문에 나도 크기가 10인 경우 9개의 원소만 넣고 10번째는 항상 빈 상태로 유지하였다.
3. 메소드
우리가 가장 많이 사용하는 push_back, pop_back을 포함하여 front, back, size, empty, clear, resize, at을 구현하였고 iterator연산에 빠질 수 없는 begin, end도 구현하였다. 코드의 길이가 꽤 길기 때문에 소스코드는 github링크를 통해 확인하기 바란다. 가장 중요한 부분이 push_back과 pop_back에서의 길이를 2배로 늘리거나 1/2로 줄이는 일이었다. 처음에 memcpy를 이용해봤으나 생각한대로 동작하지 않아 for문을 이용해 일일히 복사하는 수 밖에 없었다. resize도 마찬가지로 크기 n을 인자로 받았을 경우 10부터 2배씩 늘려 n을 포함할 수 있는 크기로 배열의 크기를 재설정하였다.
사용만하던 벡터를 직접 구현하면서 벡터에 대한 이해가 더 깊어진 것 같고 특히 iterator를 직접 구현해보고 연산자를 구현해보면서 C++에 대한 이해가 더 발전한 것 같다.
'프로젝트 > C++ STL만들기' 카테고리의 다른 글
[C++ STL 만들기] priority_queue 구현 (0) | 2021.08.19 |
---|---|
[C++ STL 만들기] queue 구현 (0) | 2021.08.02 |
[C++ STL 만들기] list 구현 (0) | 2021.07.31 |
[C++ STL 만들기] stack 구현 (0) | 2021.07.29 |