一、vector容器
template<typename T>
class Allocator{
public:T* allocator(size_t size){// 负责内存开辟return (T*)malloc(sizeof(T) * size);}void deallocate(void * p){free(p);}void construct(T*p,const T&val){// 定位newnew (p) T(val);}void destroy(T*p){p->~T();}};template<typename T, typename Alloc = Allocator<T>>
class vector{
public:vector(int size=10){// 需要把内存开辟和对象构造分开处理// _first = new T[size];_first= _allocator.allocator(size);_end = _first + size;_last =_first;}~vector(){// delete[] _first;// 析构容器有效的元素,然后释放_first指针指向的堆内存for (T* p = _first; p != _last; ++p){_allocator.destroy(p); // 把_first指针指向的数组的有效元素进行析构操作}_allocator.deallocate(_first); // 释放堆上的数组内存_first=_last=_end= nullptr;}vector(const Vector<T>& src){int size = src._last-src._first;
// _first =new T[size];_first = _allocator.allocator(size);int len=src._last-src._first;for(int i=0;i<len;i++){
// _first[i]=src._first[i];_allocator.construct(_first + i, src._first[i]);}_last = _first + len;_end = _first + size;}vector<T>& operator=(const vector<T>&src){if(this==&src){return *this;}
// delete[] _first;for (T* p = _first; p != _last; ++p){_allocator.destroy(p); // 把_first指针指向的数组的有效元素进行析构操作}_allocator.deallocate(_first);int size = src._end - src._first;int len = src._last - src._first;
// _first = new T[size];_first=_allocator.allocate(size);for (int i=0; i<len; ++i) {
// _first[i] = src._first[i];_allocator.construct(_first + i, src._first[i]);}_last = _first + len;_end = _first + size;return *this;}void push_back(const T &x) {if (full()) {resize();}
// *_last ++ = x;_allocator.construct(_last, x);_last++;}void pop_back() {if (empty()) {return;}_allocator.destroy(_last);--_last;}T back() const {if (empty()) {}return *(_last-1);}bool full() {return _end == _last;}bool empty() {return _last == _first;}void resize() {int size=_end-_first;
// T *tmp = new T[2*size];T* tmp = _allocator.allocator(2 * size);int len = _last-_first;
// for(int i=0; i<len; ++i) {
// tmp[i] = _first[i];
// }
// delete[] _first;for (int i = 0; i < size; ++i){//ptmp[i] = _first[i];_allocator.construct(tmp + i, _first[i]);}//delete[]_first;for (T* p = _first; p != _last; ++p){_allocator.destroy(p);}_allocator.deallocate(_first);_first = tmp;_end = _first + 2*size;_last = _first + len;}int size() const{return _last-_first;}T& operator[](int index){if(index<0 || index>=size()){throw "OutOfException";}return _first[index];}// 迭代器一般实现成容器的嵌套类型class iterator{public:iterator(T* ptr = nullptr):_ptr(ptr){}bool operator !=(const iterator &it) const{return _ptr !=it._ptr;}void operator++(){_ptr++;}T* operator*() {return *_ptr;}const T& operator*()const {return *_ptr;}private:T* _ptr;};// 给容器提供begin() 和end()方法iterator begin(){return iterator(_first);}iterator end(){return iterator(_last);}// for each的底层也是iteratorprivate:T* _first;T* _last;T* _end;Alloc _allocator; // // 定义容器的空间配置器对象};int main() {Test t1;Test t2;vector<Test> vec;vec.push_back(t1);vec.push_back(t2);cout << "===========================" << endl;vec.pop_back();cout << "===========================" << endl;return 0;
}
二、迭代器失效
迭代器失效是指:迭代器的底层其实就是容器的原生指针,插入元素可能导致容器内部的数据结构重新分配,从而使得原先的迭代器指向的位置不再有效;删除元素可能导致迭代器指向的位置被移动或删除,从而使得原先的迭代器不再指向期望的位置。也就是说原来的指针指向的内容被改变了,而不是现在内存中存的。
怎么判断迭代器失效没有:
容器迭代器失效增加代码,它是一个结构体维护了一个链表。cur是指向某一个结构体的指针,又定义了一个指向下一个Iterator_Base节点的地址,还定义了一个头节点。记录了用户从中获取的哪一个元素的迭代器,记录在Iterator_Base链表中,哪一个迭代器增加或删除要让其失效并重新更新。
然后判断链表中的迭代器,看它是否在插入、删除点和_last之间,将会失效,失效的话将迭代器的容器对象赋值为nullptr,再进行 operator != 、 operator++ 、 insert、erase进行操作时候,先判断迭代器是否失效。
void verify(T* first,T* last){Iterator_Base *pre = &this->_head;Iterator_Base *it =this->_head._next;while(it!= nullptr){if(it->_cur->_ptr >first && it->_cur->_ptr <=last){it->_cur->_pVec = nullptr;pre->_next =it->_next;delete it;it=pre->_next;}else{pre=it;it=it->_next;}}}
所有代码:
//
// Created by zhangchuang on 2024/4/22.
//#include <iostream>
using namespace std;
//#include <vector>template<typename T>
class Allocator{
public:T* allocator(size_t size){// 负责内存开辟return (T*)malloc(sizeof(T) * size);}void deallocate(void * p){free(p);}void construct(T*p,const T&val){// 定位newnew (p) T(val);}void destroy(T*p){p->~T();}};template<typename T, typename Alloc = Allocator<T>>
class vector{
public:vector(int size=10){// 需要把内存开辟和对象构造分开处理// _first = new T[size];_first= _allocator.allocator(size);_end = _first + size;_last =_first;}~vector(){// delete[] _first;// 析构容器有效的元素,然后释放_first指针指向的堆内存for (T* p = _first; p != _last; ++p){_allocator.destroy(p); // 把_first指针指向的数组的有效元素进行析构操作}_allocator.deallocate(_first); // 释放堆上的数组内存_first=_last=_end= nullptr;}vector(const vector<T>& src){int size = src._last-src._first;
// _first =new T[size];_first = _allocator.allocator(size);int len=src._last-src._first;for(int i=0;i<len;i++){
// _first[i]=src._first[i];_allocator.construct(_first + i, src._first[i]);}_last = _first + len;_end = _first + size;}vector<T>& operator=(const vector<T>&src){if(this==&src){return *this;}
// delete[] _first;for (T* p = _first; p != _last; ++p){_allocator.destroy(p); // 把_first指针指向的数组的有效元素进行析构操作}_allocator.deallocate(_first);int size = src._end - src._first;int len = src._last - src._first;
// _first = new T[size];_first=_allocator.allocate(size);for (int i=0; i<len; ++i) {
// _first[i] = src._first[i];_allocator.construct(_first + i, src._first[i]);}_last = _first + len;_end = _first + size;return *this;}void push_back(const T &x) {if (full()) {resize();}
// *_last ++ = x;_allocator.construct(_last, x);_last++;}void pop_back() {if (empty()) {return;}// 验证迭代器是否失效verify(_last-1, _last);// 如果是erase 验证verify(it._ptr, _last);// insert 验证verify(it._ptr, _last);_allocator.destroy(_last);--_last;}T back() const {if (empty()) {}return *(_last-1);}bool full() {return _end == _last;}bool empty() {return _last == _first;}void resize() {int size=_end-_first;
// T *tmp = new T[2*size];T* tmp = _allocator.allocator(2 * size);int len = _last-_first;
// for(int i=0; i<len; ++i) {
// tmp[i] = _first[i];
// }
// delete[] _first;for (int i = 0; i < size; ++i){//ptmp[i] = _first[i];_allocator.construct(tmp + i, _first[i]);}//delete[]_first;for (T* p = _first; p != _last; ++p){_allocator.destroy(p);}_allocator.deallocate(_first);_first = tmp;_end = _first + 2*size;_last = _first + len;}int size() const{return _last-_first;}T& operator[](int index){if(index<0 || index>=size()){throw "OutOfException";}return _first[index];}// 迭代器一般实现成容器的嵌套类型class iterator{public:iterator(vector<T,Alloc>*pvec= nullptr,T* ptr = nullptr):_ptr(ptr),_pVec(pvec){Iterator_Base* itb = new Iterator_Base(this,_pVec->_head._next);_pVec->_head._next=itb;}bool operator !=(const iterator &it) const{// 检查迭代器的有效性if(_pVec == nullptr || _pVec!=it._pVec){throw "iterator incompatable!";return false;}return _ptr !=it._ptr;}void operator++(){// 检查迭代器的有效性,迭代器失效为空if(_pVec== nullptr){throw "iterator invalid";}_ptr++;}T* operator*() {return *_ptr;}const T& operator*()const {return *_ptr;}private:T* _ptr;vector<T,Alloc> *_pVec;};// 给容器提供begin() 和end()方法iterator begin(){return iterator(_first);}iterator end(){return iterator(_last);}// 容器迭代器失效增加代码struct Iterator_Base{Iterator_Base(iterator *c = nullptr , Iterator_Base *n = nullptr):_cur(c),_next(n){}iterator *_cur;Iterator_Base *_next;};Iterator_Base _head;void verify(T* first,T* last){Iterator_Base *pre = &this->_head;Iterator_Base *it =this->_head._next;while(it!= nullptr){if(it->_cur->_ptr >first && it->_cur->_ptr <=last){it->_cur->_pVec = nullptr;pre->_next =it->_next;delete it;it=pre->_next;}else{pre=it;it=it->_next;}}}iterator insert(iterator it ,const T &val){// 1. 不考虑扩容// 2. 不考虑it._ptr的指针合法性verify(it._ptr -1 ,_last);T* p = _last;while(p>it._ptr){_allocator.construct(p,*(p-1));_allocator.destroy(p-1);p--;}_allocator.construct(p,val);_last++;return iterator(this,p);}iterator erase(iterator it ){// 1. 不考虑扩容// 2. 不考虑it._ptr的指针合法性verify(it._ptr -1 ,_last);T* p = _last;while(p<_last-1){_allocator.destroy(p);_allocator.construct(p,*(p+1));p++;}_allocator.destroy(p);_last--;return iterator(this,it._ptr);}// for each的底层也是iteratorprivate:T* _first;T* _last;T* _end;Alloc _allocator; // // 定义容器的空间配置器对象};
/*vector怎么*/#if 0
int main(){
// std::vector<int>vec{1,2,3,4,5,6,8};/*迭代器失效问题1. 删除元素for(auto it =vec.begin();it!=vec.end();it++){if(*it%2==0){vec.erase(it);}}// 2.增加元素for(auto it =vec.begin();it!=vec.end();it++){if(*it%2==0){vec.insert(it,*it-1);}}*/// 2。 解决办法 -- 更新迭代器// 删除auto it =vec.begin();while(it!=vec.end()){if(*it%2==0){it=vec.erase(it);}else{++it;}}// 增加for(auto it =vec.begin();it!=vec.end();it++){if(*it%2==0){vec.insert(it,*it-1);++it;}}}
#endif