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

安阳网站建设网络新闻发布平台发稿

安阳网站建设,网络新闻发布平台发稿,惠州网站建设制作价格,制作网页首页教程目录 一.默认成员函数 二.扩容相关函数 三.[]重载 四.修改函数 五.迭代器 继上次写完string之后,可以写一个vector练练手以及熟悉其底层。vector是一个顺序表,相比普通数组不同点在于顺序表的数据必须是连续存放的。 一.默认成员函数 string是只存放字符…

        

目录

        一.默认成员函数

        二.扩容相关函数

        三.[]重载

        四.修改函数

        五.迭代器


        继上次写完string之后,可以写一个vector练练手以及熟悉其底层。vector是一个顺序表,相比普通数组不同点在于顺序表的数据必须是连续存放的。

        一.默认成员函数

        string是只存放字符,而vector需要存放内置类型和自定义类型,所以需要引入类模板。以下是vector的最外层框架。

    template<class T>//类模板参数,T是接收外面转进来的类型,可以使内置也可以是自定义类型class vector{public://成员函数的定义private://内置成员变量是三个迭代器,vector的迭代器实际上还是指针iterator _start = nullptr; // 指向数据块的开始iterator _finish = nullptr; // 指向有效数据的尾iterator _endOfStorage = nullptr; // 指向存储容量的尾};

        以下是vector的默认成员函数,重载&和const &重载一般不需要手动写。

        vector()//默认构造函数{}vector(int n, const T& value = T())//构造一个包含n个元素的vector,每个元素都是value{resize(n, value);//直接用resize即可}template<class InputIterator>vector(InputIterator first, InputIterator last)//通过一个迭代器区间构造vector{while (first != last){push_back(*first);first++;}}vector(const vector<T>& v)//拷贝构造函数{vector tmp(v.begin(), v.end());//复用迭代器区间构造函数完成拷贝,然后再交换swap(tmp);}vector<T>& operator= (vector<T> v)//通过传值来完成拷贝,然后再交换{swap(v);return *this;}~vector()//析构函数{delete[] _start;//直接delete,由于是delete[]所以即使是多层嵌套(自定义类型或者vector或其他类型)也会调用他们的析构函数(这里需了解delete[]原理)_start = nullptr;_finish = nullptr;_endOfStorage = nullptr;}

         二.扩容相关函数

        扩容函数需要注意异地扩容时把原来空间的元素拷贝到新空间时需要使用赋值而不是memcpy或memmove。对于自定义类型并且实现了深拷贝的赋值就不会出现因为浅拷贝导致多次析构的问题。

        size_t size() const{return _finish - _start;//返回当前元素个数}size_t capacity() const{return _endOfStorage - _start;//返回总容量大小}void reserve(size_t n)//扩容{if (n > capacity())//判断目标扩容大小有没有大于总容量{T* tmp = new T[n];//直接创建新空间,大小为nsize_t sz = size();//记录扩容前的元素个数if (_start)//如果_start不为空(如果为空也不用复制元素内容了){for (int i = 0; i < sz; i++){tmp[i] = _start[i];//这里如果用memmove或者memcopy对于自定义类型会发生多次析构的问题(相当于浅拷贝),所以还是用赋值,如果自定义类型有实现深拷贝就没问题}delete[] _start;//这里把原来的删除,如果是浅拷贝,这里的删除了,tmp里面的自定义类型指针就变成野指针了}_start = tmp;//修改_start_finish = tmp + sz;//记录sz的好处_endOfStorage = tmp + n;}}void resize(size_t n, const T& value = T())//扩容或减容至n个元素,扩容的话会用value填满所有空间{if (n < size())//判断目标扩容大小是不是小于当前元素个数{T* tmp = new T[n];//直接创建新空间,大小为nfor (int i = 0; i < n; i++){tmp[i] = _start[i];//一个个拷贝,这里用赋值和reserve原因完全一样}//下面也和reserve一样delete[] _start;_start = tmp;_finish = tmp + n;_endOfStorage = tmp + n;}else if (n > size())//这里是目标扩容大小大于当前元素个数{int i = size();//记录当前元素个数reserve(n);//扩容while (i < n){_start[i++] = value;//从当前元素的结尾开始填充,直到容量达到目标扩容大小}_finish = _start + n;//更新_finish}}

        三.[]重载

        []重载需要断言是否越界,以及还要实现const版本。

        T& operator[](size_t pos)//方括号重载{assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const//const方括号重载{assert(pos < size());return _start[pos];}

        四.修改函数

        修改函数需要注意insert的pos迭代器失效问题以及erase的迭代器失效(对于外部的迭代器)。

        void push_back(const T& x)//尾插{if (_finish == _endOfStorage){reserve(capacity() == 0 ? 4 : capacity() * 2);}_start[size()] = x;//结尾插入元素_finish++;//更新_finish//或者复用insert//insert(end(),x);}void pop_back()//尾删{erase(end());//直接调用erase函数尾删}void swap(vector<T>& v)//交换两个vector的成员变量{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endOfStorage, v._endOfStorage);}iterator insert(iterator pos, const T& x)//在pos位置之前插入{assert(pos >= begin());//断言,防止pos越界assert(pos <= end());size_t sz = pos - _start;//计算并记录pos和_start的相对距离,也是待会要插入的位置if (_finish == _endOfStorage)//判断是否要扩容{reserve(capacity() == 0 ? 4 : capacity() * 2);}//重点注意,这里是insert迭代器可能失效的地方pos = _start + sz;//如果是异地扩容,那么pos所指的位置会被删除就变成野指针了,所以要更新pos位置,之前记录的sz就有用了if (size())//如果当前元素个数不为0的话{//从后往前走,然后把左边的数据挪到右边,需要注意下标的越界问题iterator end = _finish;while (end > pos){*end = *(end - 1);//左边的数据挪到右边end--;}}_start[sz] = x;//放入数据_finish++;//更新_finishreturn pos;//返回插入元素的下一个位置,也就是pos}iterator erase(iterator pos)//删除当前位置的元素{assert(pos >= begin());//判断pos是否越界assert(pos <= end());iterator prev = pos + 1;//记录pos位置的前一个位置//从左往右走,然后把右边的数据挪到左边,直接覆盖要删除的元素while (prev < end()){*(prev - 1) = *prev;//把右边的数据挪到左边prev++;}_finish--;//更新_finish//这里是第二个迭代器失效问题,如果外面的迭代器不接受erase返回的迭代器可能后面的删除会出问题return pos;//返回删除元素的下一个位置(其实还是pos)}

        五.迭代器

         vector迭代器就是原生指针,以及实现const迭代器。

        typedef T* iterator;//vector的迭代器是原生指针,和string一样typedef const T* const_iterator;//const迭代器iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}

        以上就是vector的模拟实现,写完后不仅可以提升对代码的操作熟练度,对于顺序表这种数据结构也能有更深的理解。

http://www.qdjiajiao.com/news/1106.html

相关文章:

  • 在线网站制作工具百度收录技术
  • 优站点网址收录网什么是百度竞价
  • 手机wap网站怎么做网站seo优化教程
  • 官方网站下载方法中国去中心化搜索引擎
  • 西柏坡门户网站建设规划书seo教程培训
  • 延长中路上海网站建设seo网站优化案例
  • 商丘做网站优化上海网络推广公司排名
  • 学校网站的建设需求win7优化配置的方法
  • 日本做蛋糕网站商品标题优化
  • 新网站备案查询百度快速优化软件排名
  • 去了哪找网站建设公司网站推广平台排行
  • 福州网站建设新闻什么是seo优化推广
  • 徐州网站建设的特点自己创建个人免费网站
  • wordpress快速建站教程日本shopify独立站
  • 长春怎么做网站家庭优化大师免费下载
  • 苹果网站用flash做怎么进行网络营销
  • 网站建设的步骤教程百度指数数据分析平台官网
  • 移动互联网技术优化大师班级
  • 合肥企业网站建设工seo搜索工具栏
  • 网站开发培训什么必应搜索引擎入口官网
  • 前端实战项目11套站长工具seo综合查询引流
  • 做ps找图的网站有哪些培训机构是干什么的
  • 什么网站百度收录快东莞网站建设做网站
  • php动态网站制作流程图热点军事新闻
  • h5网站价格佛山网络推广哪里好
  • 网站代备案多少钱大批量刷关键词排名软件
  • 客户拒绝做网站的理由抖音seo排名软件
  • 网站建设营销型网站海外市场推广做什么的
  • 重庆做兼职哪个网站哈尔滨最新消息
  • wordpress图文教程南宁优化网站收费