当前位置: 首页 > news >正文

网站不收录怎么办供电公司企业文化建设

网站不收录怎么办,供电公司企业文化建设,十堰网络销售,怎么做网页 在浏览器上深入篇【C】谈vector中的深浅拷贝与迭代器失效问题 Ⅰ.深浅拷贝问题1.内置类型深拷贝2.自定义类型深拷贝 Ⅱ.迭代器失效问题1.内部迭代器失效2.外部迭代器失效 Ⅰ.深浅拷贝问题 1.内置类型深拷贝 浅拷贝是什么意思#xff1f;就是单纯的值拷贝。 浅拷贝的坏处#xff1a; ①… 深入篇【C】谈vector中的深浅拷贝与迭代器失效问题 Ⅰ.深浅拷贝问题1.内置类型深拷贝2.自定义类型深拷贝 Ⅱ.迭代器失效问题1.内部迭代器失效2.外部迭代器失效 Ⅰ.深浅拷贝问题 1.内置类型深拷贝 浅拷贝是什么意思就是单纯的值拷贝。 浅拷贝的坏处 ①空间会析构两次。 ②一个修改会影响另一个。 根据上一篇vector的模拟实现中需要用到拷贝的有三个函数一个是拷贝构造一个是赋值重载一个是扩容。都需要用深度拷贝。深度拷贝是什么意思呢 就是开出一块空间将原空间的数据拷贝过来。有时候还需要将原空间释放掉。 我们可以看一下手搓的vector中的扩容就是采用的深度拷贝。 void reserve(size_t n){size_t sz size();if (n capacity()){T* temp new T[n];//首先开空间if (_start ! nullptr){//将数据拷贝到temp去memcpy(temp, _start, sizeof(T) * sz);//删除原来空间delete[] _start;}//最后将空间赋值给_start_start temp;_finish _start sz;//这里有一个问题size()的计算是用_finish -start 而这里的start已经改变而finish还没有改变//最后计算finish就变成空了最终的问题在于start改变了所有在之前要保留一份size()的数据_endstroage _start n;}}这里利用memcpy函数将数据按照字节的方式将start指向的数据一个一个拷贝到temp指向的空间里。 这个是没有问题的有问题的是这种情况当vectorstring 类型的数据扩容时会有隐藏的深拷贝。 我们知道上面的数据是vectorint类型的。即内置类型内置类型使用memcpy按照字节的方式拷贝是没有问题的。 但是不是内置类型而是自定义类型时利用memcpy拷贝可以吗 void Test4() {tao::vectorstring v;v.push_back(11111111111111111111111);v.push_back(22222222222222222222222);v.push_back(33333333333333333333333);v.push_back(44444444444444444444444);//v.push_back(55555555555555555555555);for (auto e : v){cout e ;} }当前数据实际大小并没有超过容量所以没有扩容 也没有发生拷贝所以正常但一旦我们再插入一个数据就会扩容这时原来的空间就会被释放那么能正常打印吗 很明显运行错误为什么呢 2.自定义类型深拷贝 memcpy是按照字节拷贝的拷贝完后的数据内容肯定是一样的所以_str会指向同一块数据。而当拷贝完后原空间就会被释放掉则temp里的_str就变成野指针了。 vector是深拷贝但vector空间上存的对象是string类型的数组使用memcpy会导致string对象的浅拷贝。 【解决方案】 所以我们期望这个对象能进行深拷贝就比如这个对象是string类型的我们希望能调用这个自定义类型的深拷贝。而对于那些深拷贝的自定义类型来说赋值重载必须是深拷贝的所以我们可以使用这个自定义类型的赋值重载来完成深拷贝。 //扩容------ void reserve(size_t n){size_t sz size();if (n capacity()){T* temp new T[n];//首先开空间if (_start ! nullptr){//将数据拷贝到temp去//memcpy(temp, _start, sizeof(T) * sz);for (size_t i 0; i sz; i){temp[i] _start[i];//比如_start[i] 是string类型的数据那么这里赋值给temp就会调用赋值运算符重载而string的赋值运算符重载是深度拷贝的。}//删除原来空间delete[] _start;}//最后将空间赋值给_start_start temp;_finish _start sz;//这里有一个问题size()的计算是用_finish -start 而这里的start已经改变而finish还没有改变//最后计算finish就变成空了最终的问题在于start改变了所有在之前要保留一份size()的数据_endstroage _start n;}}这样原空间释放了并不会影响temp空间里的数据。这就是隐藏的深拷贝对于vectorT呢如果T是内置类型使用memcpy就可以解决深浅拷贝但对于T是自定义类型memcpy就无法完成深拷贝了需要使用到T类型的赋值重载来深度拷贝。不过这种方法对于内置类型也是可以完成任务的。 所以我们应该将有拷贝的地方都换成上面的写法而不是用memcpy来完成拷贝。 //拷贝构造-------vector(const vectorT v)//深拷贝: _start(nullptr), _finish(nullptr), _endstroage(nullptr){_start new T[v.size()];//memcpy(_start, v._start, sizeof(T) * v.size());for (size_t i 0; i v.size(); i){_start[i] v._start[i];}_finish _startv.size();_endstroage _startv.capacity();}Ⅱ.迭代器失效问题 1.内部迭代器失效 迭代器在遍历访问的时候非常好用但有的情况下迭代器会发生失效。 什么情况下迭代器会发生失效呢 ①会引起底层空间改变的操作都有可能引起迭代器失效比如insert或者push_back插入一个数据时发生扩容。 ②erase删除一个数据时迭代器发生失效。 什么叫迭代器失效呢就是不能再访问这个迭代器了正常使用这个迭代器了。 vector和string都有insert和erase为什么string没有这个问题呢因为string中的insert和erase用的不是迭代器而是下标。 比如insert(iteraort posconst Tval)在pos位置插入数据时首先会检查是否需要扩容发现需要扩容时会开出2倍空间将原数据拷贝下来然后再将原空间释放最后将temp空间赋给start。 这时就要注意到pos迭代器就已经失效了为什么因为pos迭代器原先指向的空间被释放了现在的pos迭代器就类似一个野指针危险的很不能再去使用了。那这时insert插入的pos位置就是一个未知的空间了肯定会报错的。 【解决方法】 这里pos因为原空间被释放了变成野指针了扩容完后的start指向的空间正常但再去往pos位置去插入数据这就危险了。问题就在于pos位置我们应该在扩容直接记录一下pos的相对位置然后扩容后再更新一下pos的新位置这样pos迭代器就不会失效了。 iterator insert(iterator pos,const T val){assert(pos _start pos _finish);//首先考虑扩容----这里有一个问题迭代器失效//当迭代器扩容时这里的pos迭代器就相当于失效了因为原来的空间被释放了pos也就变成野指针了。//需要将将pos迭代器恢复需要更新pos的新位置。if (_finish _endstroage){ ------------- size_t len pos - _start;size_t newcapacity (capacity() 0 ? 4 : capacity() * 2);reserve(newcapacity);pos _start len;}//使用迭代器的好处就是可以避免string那样头插时挪动数据下标要小于0的问题因为迭代器是一个地址不可以为0的iterator end _finish - 1;while (end pos){*(end 1) *end;end--;}*pos val;_finish;//insert 中的扩容迭代器失效外部迭代器的解决方法是使用返回值将pos位置返回过去再用迭代器接收就可以对pos位置上的内容再访问了return pos;//指向新插入位置的迭代器}2.外部迭代器失效 v里面已经有了4个数据1234这时候再在第三个位置插入一个800。 然后再对这个插入位置上的数据修改一下给这个数据加上1000。 这里的迭代器失效的原因还是因为原空间被销毁pos位置变成野指针了。要注意虽然我们已经完善了内部迭代器失效但因为这里是传值传参形参的改变不会影响实参虽然形参的迭代器不会失效但是实参还是会失效的。 所以这里再次访问这个it指向的空间时就是非法的了因为it指向的空间被释放了。 tao::vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);tao::vectorint::iterator it v.begin()3;v.insert(it, 800);//这里的it---pos 形参的改变不影响实参//这里的it迭代器失效了访问的不是第三个位置了。*it 1000;for (auto e : v){cout e ;}cout endl;而标准库里的insert也会遇到这样的问题那么库里的insert是如何解决这个问题的呢 库里是用返回值的方法来解决的也就的将插入数据的位置返回回去用it来接收那么虽然形参改变无法改变实参但最后将改变后的形参以返回值的方式再传给实参实参就有效了。 tao::vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);tao::vectorint::iterator it v.begin()3;itv.insert(it, 800);//用返回值的方式将有效的迭代器(指向插入元素的位置)传送回来那样it就可以使用访问了。*it 1000;for (auto e : v){cout e ;}cout endl;以上就是insert插入操作引起的迭代器失效问题。接下来我将介绍因为erase删除操作而引起的迭代器问题。 erase操作为什么会引起迭代器失效呢 1.这里的问题不是类似于空间销毁变成野指针了而是这个迭代器代表的位置的意义改变了指向的内容不一样了。删除pos位置上的元素pos位置之后的元素就会往前挪动覆盖pos位置的元素就变成了一个新的元素了。在VS下这个行为就认定为迭代器失效了。 2.即erase以后迭代器就失效不能再访问vs会进行强制检查如果访问会直接报错。 以下面这个代码为例子删除vector中的所有偶数 tao::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(4);v.push_back(4);v.push_back(6);for (auto e : v){cout e ;}cout endl;tao::vectorint::iterator it v.begin();while (it ! v.end()){if ((*it) % 2 0){v.erase(it);//这里erase完it迭代器就失效了就无法再访问其内容了比如连续2个的偶数第一个被删除后it位置就变成第二偶数了但这个位置已经失效了所以这个偶数就无法正常删除掉了。//1 2 2 3 第一个2可以删除第二个2无法删除掉。 }else{it;//迭代器已经失效了不能再对这个迭代器操作了。}}for (auto e : v){cout e ;}cout endl; }而正常做法应该是每次删除完这个位置上的元素后都要重新赋值更新一下it库里的做法就是将erase删除位置的下一个元素的位置返回回去这样it就会更新成被删除元素的的下一个位置。 tao::vectorint::iterator it v.begin();while (it ! v.end()){if ((*it) % 2 0){itv.erase(it);//正常使用在每次删除完后对迭代器重新赋值即可。 }else{it;}}Linux和vs下对于erase删除元素后迭代器是否失效是不同的VS下对于迭代器的失效检测非常严格非常极端而g的编译器对于迭代器检测就不是很严格了。
http://www.zqtcl.cn/news/743704/

相关文章:

  • 北京微信网站开发费用软件开发做平台
  • 平面设计师必备网站精湛的赣州网站建设
  • 上海市住房和城乡建设部网站官网wordpress页面点赞
  • 试玩平台类网站怎么做的东莞网站关键词推广
  • 网站开发慕枫页面模板怎么删除
  • 网站开发微信小程序需求量大吗珠海新闻头条最新消息
  • 闭站保护对网站影响公司主网站百度收录大量网站之类的信息
  • 在阿里云上建立网站的步骤在360网站做公告怎么弄
  • wordpress给公司建站安徽省干部建设教育网站
  • 做的网站需要买什么系统服务器找第三方做网站 需要注意
  • 网页设计模板网站推荐互联网创业项目网
  • 北京做网站的大公司动态列线图怎么制作网页
  • 江西省城乡和住房建设部网站google play应用商店
  • 网站前台设计过程泰安千橙网络科技有限公司
  • 可以做来电名片的网站网站开发频道构架
  • 网站备案没通过不了宣传片拍摄的意义
  • 专业提供网站建设服务包括做解析视频网站违法莫
  • 天津工程建设协会网站wordpress 自由评论
  • 南同网站建设hr系统管理软件排名
  • 水果网店网站建设策划书做企业形象网站
  • 小清新博客网站软件公司有哪些部门
  • 企业网站托管一年多少钱想学电商运营在哪里学
  • 网站建设自评报告手机电商平台怎么做的
  • 安阳网站建设优化免费的免抠图素材网站
  • 网站主机有什么用seo网站课程
  • 网站关键词优化软件网站的二次开发
  • 网站建设技术服务费怎么入账杭州网站推广与优化
  • 咨询类网站建设方案书重庆360网络推广
  • 简单网站模板下载wordpress调用数据库字段
  • 万网空间最多放几个网站好的网站首页的特点