怎么查网站是否被k,南昌seo站内优化,网络舆情风险研判报告,小程序网站开发太原目录 使用insert时迭代器失效使用erase时迭代器失效使用memcpy浅拷贝的问题调用最匹配的函数可能出现的问题模拟实现vector 使用insert时迭代器失效
在模拟vector插入的时候会遇到扩容后pos失效的问题#xff0c;需要更新pos vector():_start(nullptr), _finish(nullptr), _e… 目录 使用insert时迭代器失效使用erase时迭代器失效使用memcpy浅拷贝的问题调用最匹配的函数可能出现的问题模拟实现vector 使用insert时迭代器失效
在模拟vector插入的时候会遇到扩容后pos失效的问题需要更新pos vector():_start(nullptr), _finish(nullptr), _endofstorage(nullptr){}void insert(iterator pos, const T value T()){assert(pos _start pos _finish);if (size() capacity()){//pos位置的空间可能在扩容的时候被delete要记录相对位置更新posint len pos - _start;reserve(capacity() 0 ? 4 : 2 * capacity());pos _start len;}iterator end _finish - 1;while (end pos){*(end 1) *end;end--;}*pos value;_finish;}
void test2(){vectorint v;v.insert(v.begin(), 1);vectorint::iterator it v.begin();v.insert(it, 2);v.insert(it, 3);v.insert(it, 4);v.insert(it, 5);//这句代码之后it就失效了v.insert(it, 6);//报错因为it传给pos的位置已经被销毁了}insert插入后it就失效了我们不知道什么时候扩容 给pos加引用的话v.insert(v.begin(), 1);是不行的因为begin返回的是临时变量的拷贝不可以修改 如果再给pos加const那pos不能更改了
所以insert之后it失效尽量不要再使用
库里的insert会返回新插入元素所在位置的迭代器
void test_vector9(){std::vectorint v3;v3.push_back(10);v3.push_back(20);v3.push_back(30);v3.push_back(40);for (auto e : v3){cout e ;//结果是10 20 30 40}cout endl;std::vectorint::iterator it v3.begin()3;int n 6;while (n--){it v3.insert(it, n);}for (auto e : v3){cout e ;//结果是10 20 30 0 1 2 3 4 5 40}cout endl;}使用erase时迭代器失效
iterator erase(iterator pos)//返回被删位置的下一个位置{assert(pos _start pos _finish);iterator it pos 1;while (it _finish){*(it - 1) *it;it;}_finish--;return pos;}void test4(){// 1 2 3 4 5// 1 2 3 4 5 6// 2 2 3 4 5vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);v.push_back(6);for (auto e : v){cout e ;}cout endl;auto it v.begin();while (it ! v.end()){if (*it % 2 0){v.erase(it);}it;}for (auto e : v){cout e ;}cout endl;}不仅会漏检查删最后一个的时候会出现 it 比_finish大的情况 vs2019会进行强制检查erase以后认为it失效了不能访问我们模拟实现的跟g下运行结果一样
erase返回被删位置的下一个位置
void test5(){//std::vectorint v;vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(4);v.push_back(5);v.push_back(6);auto it v.begin();while (it ! v.end()){if (*it % 2 0){it v.erase(it);}else{it;}}for (auto e : v){cout e ;}cout endl;}使用memcpy浅拷贝的问题
模拟实现的vector中的reserve接口中使用memcpy进行的拷贝会出现问题
memcpy会将一段内存空间中内容拷贝到另外一段内存空间中这种拷贝是浅拷贝如果T是内置类型不会有问题但如果是自定义类型就会出错
delete的时候如果是自定义的数据类型会去调用这个对象的析构函数释放的空间置成随机值查编码表之后可能就是我们不认识的字
tmp中string对象的_str和_start中string对象的_str是一样的所以_start中string对象的_str变了tmp中的也会变 调string的赋值的时候是深拷贝就可以解决问题了引用计数的浅拷贝也可以解决 库里面实现是拷贝构造的因为库里的T[]是内存池来的(就像malloc来的没有初始化)要初始化就用定位new调拷贝构造。
所以自定义类型拷贝数据不能用memcpy 如果不加也可以过但是推荐加上因为类名不是类型
调用最匹配的函数可能出现的问题 出现编译错误的原因是
会找最匹配的去调用 上面的是int和int 下面的是unsigned int 和int 上面的更匹配所以会调用模板
如果都是int那么有更匹配的就不会去实例化模板
vector(int n, const T val T())
{reserve(n);for (int i 0; i n; i){push_back(val);}
}模拟实现vector
#includeassert.h
#includeiostream
using namespace std;namespace vc
{templateclass Tclass vector{public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const iterator begin()const{return _start;}const iterator end()const{return _finish;}vector():_start(nullptr), _finish(nullptr), _endofstorage(nullptr){}template class InputIteratorvector(InputIterator first, InputIterator last){while (first ! last){push_back(*first);first;}}vector(size_t n, const T value T()){reserve(n);while (n--){push_back(value);}}vector(int n, const T value T()){reserve(n);while (n--){push_back(value);}}vector(const vectorT v)//拷贝构造:_start(nullptr), _finish(nullptr), _endofstorage(nullptr){reserve(v.capacity());for (auto e : v){push_back(e);}}vectorT operator(vectorT tmp){swap(tmp);return *this;}~vector(){delete[] _start;_start _finish _endofstorage nullptr;}T operator[](size_t pos){assert(pos size());return *(_start pos);}const T operator[](size_t pos)const{assert(pos size());return *(_start pos);}void swap(vectorT v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}size_t size() const{return _finish - _start;}size_t capacity() const{return _endofstorage - _start;}void resize(size_t n, const T value T())
//调用默认构造函数然后拷贝构造给value匿名对象具有常性要加const
//const会延长生命周期内置类型也可以认为有构造函数{if (n size()){_finish _start n;}else{reserve(n);while (_finish _start n){*_finish value;_finish;}}}void reserve(size_t n){if (n capacity()){size_t sz size();T* tmp new T[n];if (_start){//memcpy(tmp, _start,sizeof(T)*sz);//memcpy是浅拷贝自定义类型会出错for (size_t i 0; i sz; i){tmp[i] _start[i];}delete[] _start;}_start tmp;_finish tmp sz;_endofstorage tmp n;}}void push_back(const T x){if (size() capacity()){reserve(capacity()0?4:2*capacity());}*_finish x;_finish;}void pop_back(){assert(size() 0);_finish--;}iterator insert(iterator pos, const T value T())//返回新插入元素所在位置的迭代器{assert(pos _start pos _finish);if (size() capacity()){//pos位置的空间可能在扩容的时候被delete要记录相对位置更新posint len pos - _start;reserve(capacity() 0 ? 4 : 2 * capacity());pos _start len;}iterator end _finish - 1;while (end pos){*(end 1) *end;end--;}*pos value;_finish;return pos;}iterator erase(iterator pos)//返回被删位置的下一个位置{assert(pos _start pos _finish);iterator it pos 1;while (it _finish){*(it - 1) *it;it;}_finish--;return pos;}private:iterator _start;iterator _finish;iterator _endofstorage;};
}