#pragma once //迭代器模板 可以使用类模板 #include <exception> #include <string> using namespace std; template<typename T> class MyVector { public: /** 迭代器 **/ class Iterator { friend class MyVector; public: Iterator(T* pos) :m_pos(pos) { } Iterator& operator++() //前++ { ++m_pos; return *this; } Iterator operator++(int) //后++ { int* posOld = m_pos; ++m_pos; return Iterator(posOld); } Iterator& operator--()//前-- { --m_pos; return *this; } Iterator operator--(int) { int* posOld = m_pos; --m_pos; return Iterator(posOld); } bool operator==(Iterator& itr) { return (m_pos == itr.m_pos); } bool operator!=(Iterator& itr) { return !(*this == itr); } T& operator*() { return *m_pos; } T* operator->() { return m_pos; } private: T* m_pos = nullptr; //元素位置 }; public: Iterator begin(); //返回指向第一个元素的迭代器 Iterator end();//返回指向最后一个元素后面位置的迭代器 public: MyVector(); ~MyVector(); MyVector(const MyVector& obj); public: MyVector& operator=(const MyVector& obj); public: /**增加**/ void push_back(const T& nVal); /* * 其他:会抛出异常exception */ Iterator intsert(Iterator itr, const T& nVal); /* 修改 */ T& operator[](int nIdx); T& at(int nIdx); /* 删除 */ bool erase(Iterator itr); void pop_back(); /* 查询 */ Iterator find(const T& nVal); /* 其它 */ int size(); private: void CheckCapacity(); //检查内存是否足够放入新的数据 private: T* m_pData = nullptr; //保存数组元素的缓冲区 int m_nCapacity = 0; //整块内存的大小 int m_nSize = 0; //当前内存中有多少数据 private: const int m_nInitialCapacityLen = 8; //初始化内存的大小 }; //构造 初始化 template<typename T> MyVector<T>::MyVector() { m_pData = new T[m_nInitialCapacityLen]; m_nCapacity = m_nInitialCapacityLen; m_nSize = 0; } template<typename T> MyVector<T>::~MyVector() { /* * 释放资源 */ if (m_pData != nullptr) { delete[] m_pData; m_pData = nullptr; } m_nSize = 0; m_nCapacity = 0; } //返回指向第一个元素的迭代器 template<typename T> typename MyVector<T>::Iterator MyVector<T>::begin() { //数据首地址给m_pos return Iterator(m_pData); } //返回指向最后一个元素后面位置的迭代器 template<typename T> typename MyVector<T>::Iterator MyVector<T>::end() { //返回地址为数据末尾最后一个元素位置加一 没有存入新的地址的地方 return Iterator(m_pData + m_nSize); } template<typename T> MyVector<T>::MyVector(const MyVector& obj) { //拷贝构造函数 这里是浅拷贝 *this = obj; } //等号运算符重载,因为是浅拷贝,所以拷贝构造的时候不能用memcpy;否则类模板释放同一个指针 堆地址重复释放系统会崩 template<typename T> MyVector<T>& MyVector<T>::operator=(const MyVector& obj) { int i; //释放自己 if (m_pData != nullptr) { delete[] m_pData; } //申请新内存 m_pData = new T[obj.m_nCapacity]; for (i = 0; i < obj.m_nSize; i++) { m_pData[i] = obj.m_pData[i]; } m_nSize = obj.m_nSize; m_nCapacity = obj.m_nCapacity; return *this; } /* 增加 */ template<typename T> void MyVector<T>::push_back(const T& nVal) { //检查内存大小 CheckCapacity(); //存入新的数值 m_pData[m_nSize] = nVal; m_nSize++; } template<typename T> typename MyVector<T>::Iterator MyVector<T>::intsert(Iterator itr, const T& nVal) { /* * 获取索引值 */ T* pos = itr.m_pos; int nIdx = pos - m_pData; /* * 检查索引是否越界 */ if (nIdx < 0 || nIdx > m_nSize) { throw exception("索引越界"); } /* * 检查内存大小 */ CheckCapacity(); /* * 拷贝数据 */ int nSizeOfCopyData = (m_nSize - nIdx)*sizeof(T); //拷贝的数据的大小 T* pBeginPos = m_pData + nIdx; //拷贝数据的起始位置 T* pEndPos = m_pData + nIdx + 1; //拷贝数据的目的位置 memcpy(pEndPos, pBeginPos, nSizeOfCopyData); /* * 保存新的数据 */ m_pData[nIdx] = nVal; m_nSize++; return Iterator(&m_pData[nIdx]); } /* 修改 */ template<typename T> T& MyVector<T>::operator[](int nIdx) { /* * 检查索引是否越界 */ if (nIdx < 0 || nIdx >= m_nSize) { throw exception("索引越界"); } return m_pData[nIdx]; } template<typename T> T& MyVector<T>::at(int nIdx) { /* * 检查索引是否越界 */ if (nIdx < 0 || nIdx >= m_nSize) { throw exception("索引越界"); } return m_pData[nIdx]; } /* 删除 */ template<typename T> bool MyVector<T>::erase(Iterator itr) { /* * 获取索引值 */ T* pos = itr.m_pos; int nIdx = pos - m_pData; /* * 检查索引是否越界 */ if (nIdx < 0 || nIdx >= m_nSize) { throw exception("索引越界"); } /* * 拷贝数据,覆盖被删除的数据 */ T* pBeginPos = m_pData + nIdx + 1; //获取拷贝数据的起始位置 T* pEndPos = m_pData + nIdx; //获取拷贝数据的目标位置 int nSizeOfCopyData = (m_nSize - nIdx - 1)*sizeof(T); //拷贝的数据大小 memcpy(pEndPos, pBeginPos, nSizeOfCopyData); m_nSize--; return true; } template<typename T> void MyVector<T>::pop_back() { /* * 检查索引是否越界 */ if (m_nSize <= 0) { throw exception("索引越界"); } //删除数据 m_nSize--; } /* 查询 */ template<typename T> typename MyVector<T>::Iterator MyVector<T>::find(const T& nVal) { for (int i = 0; i < m_nSize; i++) { if (nVal == m_pData[i]) { return Iterator(&m_pData[i]); } } return Iterator(nullptr); } /* 其它 */ template<typename T> int MyVector<T>::size() { return m_nSize; } //检查内存是否足够放入新的数据 template<typename T> void MyVector<T>::CheckCapacity() { //内存不够,申请新内存 if (m_nSize >= m_nCapacity) { T* pData = new T[m_nCapacity * 2]; //申请新内存 memcpy(pData, m_pData, m_nCapacity * sizeof(T)); //拷贝原来的数据 delete[] m_pData; //释放原来的额内存 m_pData = pData; m_nCapacity = m_nCapacity * 2; } }