手写C++ Vector,参考QVector
类声明
template<typename T >class IteratorVector;template<typename T >class IteratorVectorConst;template<typename T >class Vector final :public ContainerBase{public:explicit Vector()noexcept;explicit Vector(uint size)noexcept;Vector(const Vector& t)noexcept;Vector(Vector&& t)noexcept;Vector& operator= (const Vector& t)noexcept;Vector& operator= (Vector&& t)noexcept;~Vector();Vector& append(const T& t)noexcept;Vector& removeAt(uint pos)noexcept;Vector& removeAt(uint pos, uint len)noexcept;Vector& insert(uint pos, const T& t)noexcept;const T& at(uint pos)const;void clear()noexcept;Vector& removeOne(const T& t, uint pos = 0, bool onlyOne = true)noexcept;uint size()const noexcept { return m_size; };uint maxSize()const noexcept { return m_maxSize; };void setStep(uint step)noexcept { m_step = step; };uint step()const noexcept { return m_step; };bool isEmpty()const noexcept { return m_size; };void resize(uint size)noexcept;void resize(uint size, const T& t)noexcept;void swap(uint first, uint second)noexcept;void removeFirst()noexcept;void removeLast()noexcept;const T& first()const;const T& last()const;T& first();T& last();bool contains(const T& t, uint pos = 0)const noexcept;size_t find(const T& t, uint pos = 0) const noexcept;template<typename Funtion>size_t find(const T& t, const Funtion& f, uint pos = 0) const noexcept;uint capacity() const noexcept { return m_capacity; };void reverse()noexcept;T& operator[](uint pos)noexcept;IteratorVector<T> begin()noexcept;IteratorVector<T> end()noexcept;IteratorVectorConst<T> begin()const noexcept;IteratorVectorConst<T> end()const noexcept;private:T* m_element;uint m_size;uint m_step;uint m_capacity;static constexpr uint m_stepUint = 10;static constexpr size_t m_npos = -1;void _throw(bool v)const{if (v)throw std::out_of_range("Vector request out of range");}void freeMemory()noexcept{if (m_element != nullptr){delete[] m_element;m_element = nullptr;}}};#define OverstepMaxAssert assert(m_capacity <= m_maxSize);
#define ElementSize sizeof(T) * m_size
函数实现
template<typename T >MContainer::Vector<T>::Vector() noexcept:Vector(0){}template<typename T >MContainer::Vector<T>::Vector(uint size) noexcept:m_size(0), m_step(m_stepUint), m_capacity(size){OverstepMaxAssertm_element = new T[m_capacity];}template<typename T >MContainer::Vector<T>::Vector(const Vector& t) noexcept{if (&t == this)return;this->m_element = new T[t.m_capacity];this->m_size = t.m_size;this->m_step = t.m_step;this->m_capacity = t.m_capacity;std::memcpy(this->m_element, t.m_element, ElementSize);}template<typename T >MContainer::Vector<T>::Vector(Vector&& t) noexcept{if (&t == this)return;this->m_element = t.m_element;this->m_size = t.m_size;this->m_step = t.m_step;this->m_capacity = t.m_capacity;t.m_element = nullptr;t.m_size = 0;t.m_capacity = 0;}template<typename T>inline Vector<T>& Vector<T>::operator=(const Vector& t) noexcept{if (&t == this)return *this;this->m_element = new T[t.m_capacity];this->m_size = t.m_size;this->m_step = t.m_step;this->m_capacity = t.m_capacity;std::memcpy(this->m_element, t.m_element, ElementSize);return *this;}template<typename T>inline Vector<T>& Vector<T>::operator=(Vector&& t) noexcept{if (&t == this)return *this;this->clear();this->m_element = t.m_element;this->m_size = t.m_size;this->m_step = t.m_step;this->m_capacity = t.m_capacity;t.m_element = nullptr;t.m_size = 0;t.m_capacity = 0;return *this;}template<typename T>inline Vector<T>::~Vector(){clear();}template<typename T>inline Vector<T>& Vector<T>::append(const T& t) noexcept{if (m_size + 1 > m_capacity){assert(m_capacity + 1 <= m_maxSize);m_capacity = m_capacity + m_step > m_maxSize ? m_maxSize : m_capacity + m_step;T* newArray = new T[m_capacity];std::memcpy(newArray, m_element, ElementSize);freeMemory();m_element = newArray;}m_element[m_size++] = t;return *this;}template<typename T >Vector<T>& MContainer::Vector<T>::removeAt(uint pos, uint len) noexcept{if (pos < 0 || pos > m_size)return *this;if (len + pos > m_size)len = m_size - pos;uint range = pos + len;uint size = m_size - range;std::memmove(m_element + pos, m_element + range, sizeof(T) * size);m_size -= len;return *this;}template<typename T>inline Vector<T>& Vector<T>::removeAt(uint pos) noexcept{return removeAt(pos, 1);}template<typename T>inline Vector<T>& Vector<T>::insert(uint pos, const T& t)noexcept{uint size = m_size + 1;if (pos > size)return *this;if (size > m_capacity){assert(m_capacity + 1 <= m_maxSize);m_capacity = m_capacity + m_step > m_maxSize ? m_maxSize : m_capacity + m_step;T* newArray = new T[m_capacity];std::memcpy(newArray, m_element, ElementSize);freeMemory();m_element = newArray;}uint count = m_size - pos;uint movePos = m_size;while (count){m_element[movePos] = m_element[movePos - 1];movePos -= 1;count--;}m_element[pos] = t;m_size++;return *this;}template<typename T>inline const T& Vector<T>::at(uint pos) const{_throw(pos >= m_size);return m_element[pos];}template<typename T>inline void Vector<T>::clear()noexcept{freeMemory();m_size = 0;m_capacity = 0;m_step = m_stepUint;}template<typename T>inline Vector<T>& Vector<T>::removeOne(const T& t, uint pos, bool onlyOne)noexcept{if (pos >= m_size)return *this;for (size_t i = 0; i < m_size; i++){if (m_element[i] == t){removeAt(i);if (onlyOne)return *this;}}return *this;}template<typename T>inline T& Vector<T>::operator[](uint pos) noexcept{_throw(pos >= m_size);return m_element[pos];}template<typename T >T& MContainer::Vector<T>::last(){_throw(!m_size);return m_element[m_size - 1];}template<typename T >T& MContainer::Vector<T>::first(){_throw(!m_size);return m_element[0];}template<typename T >bool MContainer::Vector<T>::contains(const T& t, uint pos )const noexcept{for (; pos < m_size; pos++){if (t == m_element[pos])return true;}return false;}template<typename T >const T& MContainer::Vector<T>::last()const{_throw(!m_size);return m_element[m_size - 1];}template<typename T >const T& MContainer::Vector<T>::first()const{_throw(!m_size);return m_element[0];}template<typename T >void MContainer::Vector<T>::removeLast()noexcept{removeAt(m_size - 1);}template<typename T >void MContainer::Vector<T>::removeFirst()noexcept{removeAt(0);}template<typename T >void MContainer::Vector<T>::swap(uint first, uint second)noexcept{if (first == second|| first >= m_size|| second >= m_size)return;T tmp = m_element[first];m_element[first] = m_element[second];m_element[second] = tmp;}template<typename T >void MContainer::Vector<T>::resize(uint size, const T& t)noexcept{clear();m_capacity = size;m_size = size;m_element = new T[m_capacity]{ t };}template<typename T >void MContainer::Vector<T>::resize(uint size)noexcept{resize(size, {});}template<typename T >size_t MContainer::Vector<T>::find(const T& t, uint pos)const noexcept{for (; pos < m_size; pos++){if (m_element[pos] == t)return pos;}return m_nopos;}template<typename T >template<typename Funtion>size_t MContainer::Vector<T>::find(const T& t, const Funtion& f, uint pos )const noexcept{for (; pos < m_size; pos++){if (f(this->at(pos), t))return pos;}return m_nopos;}template<typename T >void MContainer::Vector<T>::reverse() noexcept{if (isEmpty())return;T tmp;for (size_t i = 0; i < m_size / 2; i++){tmp = m_element[i];m_element[i] = m_element[m_size - 1 - i];m_element[m_size - 1 - i] = tmp;}}template<typename T >IteratorVectorConst<T> MContainer::Vector<T>::end() const noexcept{return IteratorVectorConst<T>(m_element + m_size);}template<typename T >IteratorVectorConst<T> MContainer::Vector<T>::begin() const noexcept{return IteratorVectorConst<T>(m_element);}template<typename T >IteratorVector<T> MContainer::Vector<T>::end()noexcept{return IteratorVector<T>(m_element + m_size);}template<typename T >IteratorVector<T> MContainer::Vector<T>::begin()noexcept{return IteratorVector<T>(m_element);}
迭代器
template<typename T >class IteratorVector :public std::iterator<std::random_access_iterator_tag, T>{private:friend Vector<T>;T* m_ptr;IteratorVector<T>(T* t):m_ptr(t){}public:IteratorVector<T> operator++(){return ++m_ptr;}IteratorVector<T> operator++(int){T * tmp = m_ptr;m_ptr++;return tmp;}IteratorVector<T> operator--(){return --m_ptr;}IteratorVector<T> operator--(int){T * tmp = m_ptr;m_ptr--;return tmp;}T*operator->(){return m_ptr;}T& operator*(){return* m_ptr;}bool operator!=(const IteratorVector<T>& t)const{return m_ptr != t.m_ptr;}bool operator==(const IteratorVector<T>& t)const{return m_ptr == t.m_ptr;}bool operator<(const IteratorVector<T>& t)const{return m_ptr < t.m_ptr;}bool operator>(const IteratorVector<T>& t)const{return m_ptr > t.m_ptr;}IteratorVector<T> operator+=(difference_type size)const{T* tmp = m_ptr + size;return tmp;}IteratorVector<T> operator-=(difference_type size)const{T* tmp = m_ptr - size;return tmp;}};template<typename T >class IteratorVectorConst :public std::iterator<std::random_access_iterator_tag, T>{private:friend Vector<T>;T* m_ptr;IteratorVectorConst<T>(T* t): m_ptr(t){}public:IteratorVectorConst<T> operator++(){return ++m_ptr;}IteratorVectorConst<T> operator++(int){T * tmp = m_ptr;m_ptr++;return tmp;}IteratorVectorConst<T> operator--(){-return -m_ptr;}IteratorVectorConst<T> operator--(int){T * tmp = m_ptr;m_ptr--;return tmp;}const T *operator->(){return m_ptr;}const T& operator*(){return*m_ptr;}bool operator!=(const IteratorVectorConst<T>& t)const{return m_ptr != t.m_ptr;}bool operator==(const IteratorVectorConst<T>& t)const{return m_ptr == t.m_ptr;}bool operator<(const IteratorVectorConst<T>& t)const{return m_ptr < t.m_ptr;}bool operator>(const IteratorVectorConst<T>& t)const{return m_ptr > t.m_ptr;}IteratorVectorConst<T> operator+=(difference_type size)const{T* tmp = m_ptr + size;return tmp;}IteratorVectorConst<T> operator-=(difference_type size)const{T* tmp = m_ptr - size;return tmp;}};
验证 (与QVector对比)
template <typename T1, typename T2 >
void verify(T1& t1, T2& t2 )
{auto start = std::chrono::high_resolution_clock::now();std::mt19937 rng(std::random_device{}());std::uniform_int_distribution<int> dist(0, 0xFFFFF);int size = dist(rng);for (size_t i = 0; i < size; i++){int number = dist(rng);if (number % 3 == 0){t1.append(number);t2.append(number);}else if (number % 3 == 1&& number < t2.size()){t1.insert(number, number);t2.insert(number, number);}else{if (number < t2.size()){t1.removeAt(number);t2.removeAt(number);}}}if (t1.size() != t2.size()){std::cout << "size != " << '\n';return;}auto t1Itor = t1.begin();auto t2Itor = t2.begin();for (;t1Itor != t1.end() ; t1Itor++,t2Itor++){if (*t1Itor != *t2Itor){std::cout << "Value != ; "<< '\n';}}std::cout << "Verification complete!" << '\n';auto end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> elapsed = end - start;std::cout << "Verification time: " << elapsed.count() << std::endl;
}
测试结果
为学习数据结构编写,容器可能存在问题。有建议可以留言指出,谢谢。