늙어도 심심삼아 코딩 할 수 있도록 소시적 배운 C++의 기억을 회복할 겸 C++ STL deque을 써서 static queue를 만들어 보았다. 임의의 data structure에 대한 pointer 들을 저장하되 정해진 용량까지만 저장한다. Queue size는 가변적이다. enqueue를 시작하면 정해진 용량까지만 채워지고 그 용량을 넘어서면 과거 데이터부터 자동 삭제된다. 또, dequeue할 때마다 size는 하나씩 감소한다. 즉, size는 0 ~ capacity 내에서 유동적이다.
실제 이 static queue를 써먹을 것인지는 중요하지 않다. 여기서는 C++ Class Constructor 기본 개념과 pointer에 대해 빨리 적응하고, 덤으로 C++11에 추가된 move constructor 등에 대해서도 알아 보는데 의의가 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | #include <iostream> #include <deque> template < typename _Tp> class StaticQueue { public : typedef typename std::deque<_Tp*> _Tp_Data; typedef typename _Tp_Data::iterator iterator; typedef typename _Tp_Data::const_iterator const_iterator; // default constructor explicit StaticQueue( size_t capa=100) : m_size(0), m_capacity(capa) { m_dequeue_item = new _Tp; m_data = new _Tp_Data; } // destructor ~StaticQueue() { destroy(); } // copy constructor StaticQueue( const StaticQueue& rhs) { copyFrom(rhs); } // copy assignment operator StaticQueue& operator=( const StaticQueue& rhs) { if ( this !=&rhs) { destroy(); copyFrom(rhs); } return * this ; } #if __cplusplus >= 201103L // move constructor: -std=c++11 StaticQueue(StaticQueue&& rhs) { moveFrom(rhs); } // move assignment operator: -std=c++11 StaticQueue& operator=(StaticQueue&& rhs) { if ( this !=&rhs) { destroy(); moveFrom(rhs); } return * this ; } #endif // index operator const _Tp& operator[]( size_t index) const { return *m_data->at(index); } _Tp& operator[]( size_t index) { return *m_data->at(index); } // getters size_t size() const { return m_size; } size_t capacity() const { return m_capacity; } _Tp_Data* data() const { return m_data; } // setters void setCapacity( size_t size) { m_capacity = size; } void enqueue( const _Tp& item); void enqueue(_Tp* item); #if __cplusplus >= 201103L // rvalue reference parameter: -std=c++11 void enqueue(_Tp&& item); #endif const _Tp& dequeue(); bool isEmpty() const { return !m_size; } void print() const ; private : void popFront(); void copyFrom( const StaticQueue& rhs); void moveFrom(StaticQueue& rhs); void destroy(); size_t m_size; // Current queue size size_t m_capacity; // Maximum queue size _Tp* m_dequeue_item; // Storage for a dequeued item _Tp_Data* m_data; // Queue container for storing FIFO data }; template < typename _Tp> inline void StaticQueue<_Tp>::enqueue( const _Tp& item) { m_data->push_back( new _Tp(item)); if (++m_size > m_capacity) { popFront(); m_size = m_capacity; } } template < typename _Tp> inline void StaticQueue<_Tp>::enqueue(_Tp* item) { m_data->push_back(item); if (++m_size > m_capacity) { popFront(); m_size = m_capacity; } } #if __cplusplus >= 201103L template < typename _Tp> inline void StaticQueue<_Tp>::enqueue(_Tp&& item) { m_data->push_back( new _Tp(item)); if (++m_size > m_capacity) { popFront(); m_size = m_capacity; } } #endif template < typename _Tp> inline const _Tp& StaticQueue<_Tp>::dequeue() { // What if undeflow condition(m_size==0)? if (m_size) { *m_dequeue_item = *m_data->front(); popFront(); --m_size; } return *m_dequeue_item; } template < typename _Tp> inline void StaticQueue<_Tp>::print() const { std::cout << "\nQueue size/capacity: " << size() << "/" << capacity() << std::endl; if (!isEmpty()) { int c = 0; for (const_iterator i=m_data->begin(); i != m_data->end(); ++i) { std::cout << c++ << ": " ; (*i)->print(); } } } template < typename _Tp> inline void StaticQueue<_Tp>::popFront() { delete m_data->front(); m_data->pop_front(); } template < typename _Tp> inline void StaticQueue<_Tp>::copyFrom( const StaticQueue<_Tp>& rhs) { m_size = rhs.m_size; m_capacity = rhs.m_capacity; m_dequeue_item = new _Tp(*rhs.m_dequeue_item); m_data = new _Tp_Data; for ( size_t i=0; i < rhs.m_size; ++i) { _Tp* item = new _Tp(rhs[i]); m_data->push_back(item); } } template < typename _Tp> inline void StaticQueue<_Tp>::moveFrom(StaticQueue<_Tp>& rhs) { m_size = rhs.m_size; m_capacity = rhs.m_capacity; m_dequeue_item = rhs.m_dequeue_item; m_data = rhs.m_data; rhs.m_size = 0; rhs.m_capacity = 0; rhs.m_dequeue_item = 0; rhs.m_data = 0; } template < typename _Tp> inline void StaticQueue<_Tp>::destroy() { if (m_dequeue_item) delete m_dequeue_item; m_dequeue_item = 0; if (!isEmpty()) { for (iterator i=m_data->begin(); i != m_data->end();) { delete *i; i = m_data->erase(i); } } if (m_data) delete m_data; m_data = 0; } |
참고 사항
구글 blogger에 소스 코드 삽입시 Syntax Highlighter를 사용하는 방법은 아래의 사이트 참조.
http://oneqonea.blogspot.kr/2012/04/how-do-i-add-syntax-highlighting-to-my.html
댓글 없음:
댓글 쓰기