Vector란 컨테이너는 자동으로 사이즈를 바꿔주는 배열입니다.
size 라는 실제로 사용하고 있는 사이즈값과
capacity 라는 size가 초과되려고 할 때, 여분의 공간값이 주어집니다.
즉 내가 사용하려는 벡터의 index == size이 되었을 때, resize()함수를 통하여
capacity를 공간을 늘려주고 실제 사용할 수 있는 메모리값이 동적으로 할당됩니다.
이를 통하여 저만의
size()
capactiy()
resize()
push_back()
operator[] 기능만 간단하게 가지도록 코드를 짜봅니다.
#include <iostream>
using namespace std;
template <typename T> class VECTOR {
private:
T* mPtr;
int mSize;
int mCapacity;
int mIndex;
public:
VECTOR(int s = 0) : mSize(s), mCapacity(s), mIndex(0) {
mPtr = new T[mCapacity];
}
int size() { return mSize; }
int capacity() { return mCapacity; }
// we should resize the vactor.
void resize(int s) {
if (s <= mCapacity) mSize s;
else {
mCapacity = s * 2;
mSize = s;
T* tmp = new T[mCapacity];
memcpy(tmp, mPtr, sizeof(T) * mSize);
delete[] mPtr;
mPtr = tmp;
}
}
void push_back(const T& value) {
if (mIndex == mSize)
resize(mSize + 1);
*(mPtr + mIndex++) = value;
}
T& operator[] (int i) {
return *(mPtr + i)
}
};
push_back() 함수를 통하여 VECTOR란 컨테이너의 뒤부터 값이 들어갑니다.
이때, index가 size와 같은 값을 같게 되었을때, resize(size + 1)로 함수를 호출합니다.
size + 1 < capacity 인 경우에는 mSize + 1 로 값만 바꾸고,
size + 1 > capacity인 경우에는 capacity를 size의 2배만큼 늘려주고 할당해 줍니다.
(이때, memcpy를 통해 현재 값을 할당해줍니다.)
추가적으로 iterator도 구현하여서 vector을 순회할 수 있도록 해보았습니다.
iterator
template <typename T> class VECTOR_iterator {
T* current;
public:
VECTOR_iterator(T* p = 0) : current(p) {}
template<typename U> bool operator!=(U data) { return current != data; }
bool operator!=(const VECTOR_iterator& p) { return current != p.current; }
VECTOR_iterator& operator++() {
current = current + 1;
return *this;
}
VECTOR_iterator& operator++(int) {
current = current + 1;
return *this;
}
T& operator*() { return *current; }
};
VECTOR
template <typename T> class VECTOR {
private:
T* mPtr;
int mSize;
int mCapacity;
int mIndex;
public:
VECTOR(int s = 0) : mSize(s), mCapacity(s), mIndex(0) {
mPtr = new T[mCapacity];
}
int size() { return mSize; }
int capacity() { return mCapacity; }
// we should resize the vactor.
void resize(int s) {
if (s <= mCapacity) mSize = s;
else {
mCapacity = s * 2;
mSize = s;
T* tmp = new T[mCapacity];
memcpy(tmp, mPtr, sizeof(T) * mSize);
delete[] mPtr;
mPtr = tmp;
}
}
void push_back(const T& value) {
if (mIndex == mSize)
resize(mSize + 1);
*(mPtr + mIndex++) = value;
}
T& operator[] (int i) {
return *(mPtr + i);
}
typedef VECTOR_iterator<T> iterator;
iterator begin() { return iterator(mPtr);}
iterator end() { return iterator(mPtr+mSize);}
};
이렇게 된다면,
int main()
{
VECTOR<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
for (auto i : v) cout << i << endl;
}
자연스럽게 vector도 순회할 수 있습니다.
추가로 for(auto i: v)의 구문은
for (VECTOR<int>::iterator i = v.begin(); i != v.end(); i++) {
cout << *i << endl;
}
이 구문과 의미가 같습니다.