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

做cpa联盟必须要有网站吗保定网络推广公司

做cpa联盟必须要有网站吗,保定网络推广公司,网站建筑设计,wordpress维护主题目录 vector介绍 vector示意图 关于vector扩容的问题 vector框架 构造函数 析构函数 vector有关空间容量函数 insert和erase pop_back和push_back 其它构造函数 拷贝构造 迭代器区间构造 运算符重载 关于迭代器失效问题【重点】 有关insert发生迭代器失效 有关…目录 vector介绍 vector示意图  关于vector扩容的问题 vector框架 构造函数 析构函数  vector有关空间容量函数 insert和erase pop_back和push_back 其它构造函数 拷贝构造 迭代器区间构造 运算符重载 关于迭代器失效问题【重点】 有关insert发生迭代器失效 有关erase发生迭代器失效 vector模拟实现整体代码 vector介绍 1. vector 是表示可变大小数组的序列容器就像数组一样vector 也采用的连续存储空间来存储元素。也就是意味着可以采用下标对 vector 的元素进行访问和数组一样高效。但是又不像数组它的大小是可以动态改变的而且它的大小会被容器自动处理。 2. 本质讲 vector 使用动态分配数组来存储它的元素。当新元素插入时候这个数组需要被重新分配大小为了增加存储空间。其做法是分配一个新的数组然后将全部元素移到这个数组。就时间而言这是一个相对代价高的任务因为每当一个新的元素加入到容器的时候vector 并不会每次都重新分配大小。 3. vector 分配空间策略 vector 会分配一些额外的空间以适应可能的增长因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何重新分配都应该是对数增长的间隔大小以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。 4. 与其它动态序列容器相比 deque, list and forward_list vector 在访问元素的时候更加高效在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作效率更低。比起list 和 forward_list统一的迭代器和引用更好 vector示意图  上面的图片来自于《STL源码剖析》这本书从图中我们就可以看出vector实现的基本形式。vector类的成员变量是三个指针指向起始位置的 _start 指向最后一个数据的下一个位置的_finish指向容量的下一个位置的_end_of_storage。  关于vector扩容的问题 使用以下一段demo进行测试 void TestVectorExpand() {size_t sz;vectorint v;sz v.capacity();cout making v grow:\n;for (int i 0; i 100; i){v.push_back(i);if (sz ! v.capacity()){sz v.capacity();cout capacity changed: sz \n;}} } 在VS2022下大致为1.5倍 在gcc下2倍 vector框架 templateclass T class vector { public:typedef T* iterator;typedef const T* const_iterator;private:iterator _start nullptr;iterator _finish nullptr;iterator _endofstorage nullptr; }; 构造函数 vector():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr) {} 析构函数  ~vector() {delete[] _start;_start _finish _endofstorage nullptr; } vector有关空间容量函数 size_t capacity() const {return _endofstorage - _start; }size_t size() const {return _finish - _start; }bool empty()const {return size() 0; }void reserve(size_t n) {if (n capacity()){T* tmp new T[n];size_t sz size();if (_start){//memcpy(tmp, _start, sizeof(T) * sz);for (size_t i 0; i sz; i){tmp[i] _start[i];}delete[] _start;}_start tmp;_finish _start sz;_endofstorage _start n;} }void resize(size_t n, const T val T()) {if (n size()){_finish _start n;}else{reserve(n);while (_finish _start n){*_finish val;_finish;}} } 需要注意的是关于reserve函数当数值大于当前vector的容量时需要进行拷贝使用memcpy进行拷贝时浅拷贝对于内置类型不会有问题 但是对于自定义类型就会有问题比如string 会引发扩容就会引发对旧内容进行拷贝如果使用memcpy进行拷贝会出问题 问题如下 拷贝完以后浅拷贝回来对应指针当旧对象释放后新对象指向的内容就无意义了这就是问题所在解决办法如上面reserve函数。 insert和erase iterator insert(iterator pos, const T x) {assert(pos _start);assert(pos _finish);if (_finish _endofstorage){size_t len pos - _start;reserve(capacity() 0 ? 4 : capacity() * 2);pos _start len;}iterator end _finish - 1;while (end pos){*(end 1) *end;--end;}*pos x;_finish; }iterator erase(iterator pos) {assert(pos _start);assert(pos _finish);iterator it pos 1;while (it _finish){*(it - 1) *it;it;}--_finish;return pos; } pop_back和push_back void push_back(const T x) {if (_finish _end_of_storage){reserve(capacity() 0 ? 4 : capacity() * 2);}*_finish x;_finish; }void pop_back() {assert(_finish _start);_finish--; } 其它构造函数 拷贝构造 vector(int n, const T val T()) {reserve(n);for (int i 0; i n; i){push_back(val);} }vector(const vectorT v) {reserve(v.capacity());for (auto e : v){push_back(e);} } 迭代器区间构造 template class InputIterator vector(InputIterator first, InputIterator last) {while (first ! last){push_back(*first);first;} } 运算符重载 void swap(vectorT v) {std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage); }vectorT operator(vectorT tmp) {swap(tmp);return *this; }T operator[](size_t pos) {assert(pos size());return _start[pos]; }const T operator[](size_t pos) const {assert(pos size());return _start[pos]; } 关于迭代器失效问题【重点】 vector是一个动态数组它在内存中连续存储由于vector在内存中连续存储因此当进行某些操作时迭代器可能会失效。 插入元素(可能会导致内存重新分配)在vector中插入元素可能会导致整个容器重新分配内存这种情况下所有指向容器中元素的迭代器都会失效。 删除元素从vector中删除元素会导致被删除元素之后的迭代器失效这是因为删除操作可能会移动容器中其他元素以填补被删除元素的空位然而指向被删除元素之前的迭代器仍然有效。 重新分配任何导致vector重新分配内存的操作都会使所有迭代器失效。 有关insert发生迭代器失效 迭代器失效原因 insert时迭代器失效发生在insert前sizecapacity当insert时会先扩容但是扩容后pos还是指向原来的空间的位置且已经被释放那么当再次使用pos时就会导致程序崩溃 解决办法更新pos位置迭代器使其指向扩容后对应的位置并返回pos位置迭代器。 iterator insert(iterator pos, const T x) {assert(pos _start);assert(pos _finish);if (_finish _endofstorage){size_t len pos - _start;reserve(capacity() 0 ? 4 : capacity() * 2);pos _start len;}iterator end _finish - 1;while (end pos){*(end 1) *end;--end;}*pos x;_finish;return pos; } 通过查阅文档也可以发现官方的做法也是返回Insert位置的迭代器 有关erase发生迭代器失效 erase函数错误写法 void erase(iterator pos) {assert(pos _start);assert(pos _finish);iterator begin pos 1;while (begin _finish){*(begin - 1) *begin;begin;}_finish--; } 演示代码 运行结果 出错原因 it永远不会等于finish 解决办法返回pos位置迭代器 iterator erase(iterator pos) {assert(pos _start);assert(pos _finish);iterator it pos 1;while (it _finish){*(it - 1) *it;it;}--_finish;return pos; } 对应示例 void test() {vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);//删除所有偶数auto it v.begin();while(it ! v.end()){if(*it % 2 0){it v.erase(*it);}else{it;}}for(auto e : v){cout e ;} } 通过查阅文档也可以发现官方的做法也是返回erase位置的迭代器 vector模拟实现整体代码 templateclass T class 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(){}template class InputIteratorvector(InputIterator first, InputIterator last){while (first ! last){push_back(*first);first;}}vector(size_t n, const T val T()){reserve(n);for (size_t i 0; i n; i){push_back(val);}}vector(int n, const T val T()){reserve(n);for (int i 0; i n; i){push_back(val);}}vector(const vectorT v){reserve(v.capacity());for (auto e : v){push_back(e);}}void swap(vectorT v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}vectorT operator(vectorT tmp){swap(tmp);return *this;}~vector(){delete[] _start;_start _finish _endofstorage nullptr;}void reserve(size_t n){if (n capacity()){T* tmp new T[n];size_t sz size();if (_start){//memcpy(tmp, _start, sizeof(T) * sz);for (size_t i 0; i sz; i){tmp[i] _start[i];}delete[] _start;}_start tmp;_finish _start sz;_endofstorage _start n;}}void resize(size_t n, const T val T()){if (n size()){_finish _start n;}else{reserve(n);while (_finish _start n){*_finish val;_finish;}}}void push_back(const T x){/*if (_finish _endofstorage){reserve(capacity() 0 ? 4 : capacity() * 2);}*_finish x;_finish;*/insert(end(), x);}iterator insert(iterator pos, const T x){assert(pos _start);assert(pos _finish);if (_finish _endofstorage){size_t len pos - _start;reserve(capacity() 0 ? 4 : capacity() * 2);pos _start len;}iterator end _finish - 1;while (end pos){*(end 1) *end;--end;}*pos x;_finish;return pos;}iterator erase(iterator pos){assert(pos _start);assert(pos _finish);iterator it pos 1;while (it _finish){*(it - 1) *it;it;}--_finish;return pos;}T operator[](size_t pos){assert(pos size());return _start[pos];}const T operator[](size_t pos) const{assert(pos size());return _start[pos];}size_t capacity() const{return _endofstorage - _start;}size_t size() const{return _finish - _start;}private:iterator _start nullptr;iterator _finish nullptr;iterator _endofstorage nullptr; };
http://www.dnsts.com.cn/news/241734.html

相关文章:

  • 永久免费网站建设项目推广方案怎么写
  • 网站优化效果怎么样广东新闻联播2011
  • 什么网站做网页好网站三合一建设
  • 网站建设需求分析流程图wordpress文章全显示
  • 做农资的网站如何把网站主关键词做到百度首页
  • 解决wordpress更改新域名后网站不能访问的问题做嗳嗳的网站
  • 建设厅证书查询网站浙江网站建设哪家好
  • 珠海市 网站建设服务器安全加固
  • 无锡华士镇网站建设重庆建设工程信息网官网入渝备案
  • 企业网站建设需要哪些设备上海南京东路网站建设
  • 无锡做百度网站阜阳网站建设价格低
  • 清河网站建设设计东莞网站开发报价
  • 什么网站做软文锦州网站开发招聘
  • 个人免费网站申请注册模板展示网站源码
  • 东莞品牌网站建设wordpress需要安装哪些插件
  • 网站制作公司高端怎么做网站发货
  • 即买即送的网站有哪些禁止WordPress访问官网
  • dedecms5.7 财经网站广东外贸网站建设企业
  • 美食网站建设的思路佛山市顺德区建设局网站
  • 开发网站需要哪些技术人员如何进行app推广
  • 遂溪 网站电商网站如何备案
  • 网站运营维护工作 基本内容包括门户网站定制开发
  • 响应式网站怎么样源代码做的网站好用么
  • 宁夏建设工程招投标管理中心网站wordpress 自定义模板下载
  • 手机和wap网站建设网站建设用阿里还是华为云
  • 有网站吗推荐一下网站搭建多少钱logo修改
  • 网站描述和关键词怎么写建设工程合同违约金上限
  • 阿里服务器怎么做网站服务器自适应网站欣赏
  • 扁平化设计网站建设创建网站
  • 网站后台上传缩略图网站开发需要用到哪些技术