#include <iostream>
using namespace std;
#include <vector>
// 주제 : vector
template<typename T>
class Iterator // 반복자
{
public:
Iterator() : _ptr(nullptr)
{
}
Iterator(T* ptr) : _ptr(ptr)
{
}
Iterator& operator++()
{
_ptr++;
return *this;
}
Iterator operator++(int)
{
Iterator temp = *this;
_ptr++;
return temp;
}
Iterator& operator--()
{
_ptr--;
return *this;
}
Iterator operator--(int)
{
Iterator temp = *this;
_ptr--;
return temp;
}
Iterator operator+(const int count)
{
Iterator temp = *this;
temp._ptr += count;
return temp;
}
Iterator operator-(const int count)
{
Iterator temp = *this;
temp._ptr -= count;
return temp;
}
bool operator==(const Iterator& right)
{
return _ptr == right._ptr;
}
bool operator!=(const Iterator& right)
{
return !(*this == right);
}
T& operator*()
{
return *_ptr;
}
public:
T* _ptr; // 반복자는 포인터를 멤버변수로 들고있다
};
template<typename T>
class Vector
{
public:
Vector() : _data(nullptr), _size(0), _capacity(0)
{
}
~Vector()
{
if (_data != nullptr) // if(_data) 라고 해도 됨
delete[] _data;
}
// []
void push_back(const T& val) // val을 참조값을 받았는데 int같은 일반적인 타입을 아닐 경우도 생각
{
if (_size == _capacity) // 여유 공간이 없을 때 예외 처리
{
// 증설 작업
int newCapacity = static_cast<int>(_capacity * 1.5); // 여유공간을 1.5배 증가
if (newCapacity == _capacity) // int로 캐스팅했기 때문에 소수점 잘리는 경우 처리
newCapacity++;
reserve(newCapacity); // 새로운 여유 공간으로 예약
}
// 데이터 저장
_data[_size] = val; // 포인터는 배열과 유사함
// 데이터 개수 증가
_size++;
}
void reserve(int capacity)
{
_capacity = capacity; // 멤버 변수의 값을 변경
T* newData = new T[_capacity]; // 새로운 동적할당 배열을 새로운 값으로 생성
// 데이터 복사
for (int i = 0; i < _size; i++) // 공간만 만들었지 값은 이동하지 않았기 때문에 이전
newData[i] = _data[i];
// 기존에 있던 데이터 날린다
if (_data)
delete[] _data; // delete[]을 사용했기에 모든 데이터가 날아간다
_data = newData; // 새 데이터를 멤버변수로 이동
}
T& operator[](const int pos) { return _data[pos]; } // 포인터 값 출력
int size() { return _size; }
int capacity() { return _capacity; }
public:
typedef Iterator<T> iterator; // Iterator iterator가 아닌 typedef으로 들고있다. 앞의 버전은 왜 안되지?
void clear() { _size = 0; }
iterator begin() { return iterator(&_data[0]); } // iterator 생성자를 이용해 첫 주소를 넣어줌
iterator end() { return begin() + _size; }
public:
T* _data; // 벡터도 배열이다. 포인터로 첫 주소를 들고있자
int _size; // 내가 진짜 할당한 양
int _capacity; // 벡터가 품을수 있는 수용 공간
};
int main()
{
Vector<int> v;
//v.reserve(100);
for (int i = 0; i < 100; i++)
{
v.push_back(i);
cout << v.size() << " " << v.capacity() << endl;
}
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << endl;
}
cout << "--------------------" << endl;
for (Vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << (*it) << endl;
}
return 0;
}