C++ 복습하려고 만드는 std::array 라이브러리
namespace 가 겹치지 않도록 mystd 안에 array 클래스와 array_iterator, array_const_iterator를 선언했다.
iterator 클래스는 구조를 파악하기 어려워 정의와 선언을 참고해가면서 만들었다.
{} 를 사용하는 유니폼 초기화까지 구현하고 싶었는데 안되더라
근데 뭐... 코딩테스트에서 유니폼 초기화를 사용하는 일은 없으니까 ㅇ3ㅇ
#include <iostream>
#include <array>
#include <vector>
using std::cout;
using std::endl;
namespace mystd {
// 유니폼 초기화 안돼요
using size_t = unsigned int;
template<typename T, size_t _size>
class array_const_iterator {
private:
const T* ptr;
size_t offset;
public:
array_const_iterator():offset(0) {
}
array_const_iterator(const T* ptr, size_t offset = 0):ptr(ptr), offset(offset) {
}
// non-const
const array_const_iterator& operator++() {
++ptr;
return *this;
}
// const
const array_const_iterator operator++(int) {
array_const_iterator temp = *this;
++(*this);
return temp;
}
const array_const_iterator& operator--() {
--ptr;
return *this;
}
const array_const_iterator operator--(int) {
array_const_iterator temp = *this;
--(*this);
return temp;
}
const T& operator+=(size_t idx) {
offset += idx;
return *this;
}
const T operator+(size_t idx) const {
array_const_iterator temp = *this;
return temp += idx;
}
const T& operator[](size_t idx) const{
return *(*this + offset);
}
const T* operator->() const {
return ptr + offset;
}
const T& operator*() const {
return *operator->();
}
};
template<typename T, size_t _size>
class array_iterator {
private:
T* ptr; // beginning of array
size_t idx;
public:
array_iterator() {
}
array_iterator(T* elements, size_t offset = 0)
: ptr(elements), idx(offset) {
}
/* 증감연산자 */
array_iterator& operator++() {
++idx;
return *this;
}
const array_iterator operator++(int) {
array_iterator temp = *this;
++(*this);
return temp;
}
array_iterator& operator--() {
--idx;
return *this;
}
const array_iterator operator--(int) {
array_iterator temp = *this;
--(*this);
return temp;
}
array_iterator& operator+=(const size_t idx) {
this->idx += idx;
cout << "operator+=" << endl;
cout << "this의 주소" << this << endl; //같
return *this;
}
array_iterator operator+(const size_t idx) const {
array_iterator temp = *this;
cout << "operator+" << endl;
cout << "this의 주소" << this << endl; // 다름
cout << "temp의 주소" << &temp << endl; //같
// return temp += idx;
array_iterator& t_ref = (temp += idx);
cout << "t_ref의 주소" << &t_ref << endl; //같
return t_ref;
}
/* 비교연산자 */
bool operator==(const array_iterator& right) const {
return this->idx == right.idx;
}
bool operator!=(const array_iterator& right) const {
return !(*this == right);
}
/* 접근연산자 */
T& operator[](const size_t idx) const{
return *(*this + idx);
}
T* operator->() const{
return ptr+idx;
}
/* 참조연산자 */
T& operator*() const {
return *operator->();
}
};
template <typename T, size_t _size>
class array {
private:
T arr[_size];
//size_t N;
public:
using iterator = array_iterator<T, _size>;
using const_iterator = array_const_iterator<T, _size>;
/*array(): N(_size) {}
array(array<T, _size> &right) {
this->N = right.N;
for (size_t i =0 ; i < N; i++) {
arr[i] = right.arr[i];
}
}*/
T at(size_t index) const {
if (_size <= index) {
throw std::out_of_range("overflow");
}
return arr[index];
}
// non-const
T& at(size_t index) {
// const this*
if (_size <= index) {
throw std::out_of_range("overflow");
}
return arr[index];
}
T& back() {
return arr[_size - 1];
}
const T back() const {
return arr[_size - 1];
}
T& front() {
return arr[0];
}
const T front() const {
return arr[0];
}
iterator begin() {
return iterator(arr, 0);
}
iterator end() {
return iterator(arr, _size);
}
size_t size() const {
return _size;
}
bool empty() const {
return _size == 0;
}
T& operator[](size_t index) {
return arr[index];
}
T operator[](size_t index) const {
return arr[index];
}
void swap(array<T, _size>& right) {
array<T, _size> temp = *this;
*this = right;
right = temp;
}
};
// ty = type
template <typename type>
class vector {
private:
public:
vector() {
}
vector
};
}
int main() {
mystd::array<int, 5> myarray;
mystd::array<int, 5> yourarray;
for(size_t i = 0; i<5; i++){
myarray[i] = i;
yourarray[i] = i * 100;
}
myarray.swap(yourarray);
cout << " " << endl;
mystd::array<int, 5>::iterator m_iter = myarray.begin();
for (mystd::array<int, 5>::iterator it = myarray.begin(); it != myarray.end(); it++) {
cout << *it << endl;
}
cout << " " << endl;
for (size_t i = 0; i < 5; i++) {
cout << m_iter[i] << endl;
}
std::array<int, 3> arr{ 1,2,3 };
std::array<int, 3> brr;
std::array<int, 3>::const_iterator it = arr.begin();
for (size_t i = 0; i < 3; i++) {
cout << it[i] << endl;
}
for (std::array<int, 3>::const_iterator it = arr.begin(); it != arr.end(); it++) {
//cout << *it << endl;
//*it = 5;
}
std::array<int, 3>::iterator iter;
std::vector<int> v{ 1,2,3 };
std::cout << std::boolalpha << " " << arr.empty();
}
만들면서 드는 생각은 C++의 총집합체 같다
연산자 오버로딩은 기본이고 template을 다양하게 사용하는 법, const, 레퍼런스, 포인터 안쓰는게 하나도 없네
짜는도중 바보같이 함수 내부에서 지역변수를 만들어서 레퍼런스로 반환하는 실수를 했었다 ㅋㅋㅋㅋㅋ
디버깅해봤는데 갑자기 this값이 쓰레기값이 되더라
레퍼런스 반환 함수를 구현할때는 앞으로 특히 신경써야겠다
내일은 벡터를 구현해봐야지
재밌긴 재밌지만 어렵고 빡치는 씨쁠쁠