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

用py做网站外行做网站

用py做网站,外行做网站,地方网站系统,网站制作可能出现的问题文章目录 全部的实现代码放在了文章末尾准备工作包含头文件定义命名空间和类类的成员变量 迭代器迭代器获取函数 构造函数默认构造使用n个值构造迭代器区间构造解决迭代器区间构造和用n个值构造的冲突拷贝构造 析构函数swap【交换函数】赋值运算符重载emptysize和capacityopera… 文章目录 全部的实现代码放在了文章末尾准备工作包含头文件定义命名空间和类类的成员变量 迭代器迭代器获取函数 构造函数默认构造使用n个值构造迭代器区间构造解决迭代器区间构造和用n个值构造的冲突拷贝构造 析构函数swap【交换函数】赋值运算符重载emptysize和capacityoperator[]reserve【调整容量大小】resize【调整size大小】push_backassign【把所有数据替换成迭代器区间中的数据】insert为什么扩容会导致pos迭代器失效为什么要返回pos-1 erase为什么要返回pos 全部代码 全部的实现代码放在了文章末尾 准备工作 创建两个文件一个头文件myvector.hpp一个源文件 tesr.cpp 【因为模板的声明和定义不能分处于不同的文件中所以把成员函数的声明和定义放在了同一个文件myvector.hpp中】 mystring.h存放包含的头文件命名空间的定义成员函数和命名空间中的函数的定义 test.cpp存放main函数以及测试代码 包含头文件 iostream用于输入输出 assert.h用于使用报错函数assert 定义命名空间和类 在文件myvector.hpp中定义上一个命名空间myvector 把vector类和它的成员函数放进命名空间封装起来防止与包含的头文件中的函数/变量重名的冲突问题 类的成员变量 参考了stl源码中的vector的实现 成员变量有3个都是迭代器 画图理解一下 迭代器 迭代器 因为存放数据的空间是从堆区申请的连续的内存且只是简单模拟 所以我用了指针T*作为普通迭代器const T*作为const迭代器 【T是vector中存储的数据的类型】 直接把T*重命名为iterator把const T*重命名为const_iterator就完成了迭代器的实现 迭代器获取函数 因为const修饰的对象只能调用const修饰的成员函数 所以如果是const修饰的对象调用begin()和end()的时候就会自动调用到const修饰的begin和end. 构造函数 默认构造 因为stl库里实现的默认构造是没开空间的所以默认构造直接让3个成员变量都为nullptr就行 直接在声明的时候给缺省值缺省值会传给成员初始化列表 即 而成员初始化列表会比构造函数先调用 并且每个构造函数调用之前都会先调用成员初始化列表这样不管调用哪一个构造函数初始化都会先把3个成员变量初始化成nullptr 使用n个值构造 迭代器区间构造 解决迭代器区间构造和用n个值构造的冲突 当重载了迭代器区间构造和用n个值构造的时候 如果传入的两个参数都是int类型的话就会报错 为什么 因为在模板函数构成重载时编译器会调用更合适的那一个 什么叫更合适 就是不会类型转 如果传入的两个参数都是int类型那么调用的应该是使用n个值构造因为没有int类型的迭代器 但是使用n个值构造的第一个参数是size_t,int传进去要隐式类型转换 而调用迭代器区间构造两个int的实参传进去就会直接把InputIterator推导成int不会发生类型转换所以编译器会调用迭代器区间构造 解决方法 再重载一个使用n个值构造的函数把第一个参数改成int 拷贝构造 因为成员申请了堆区空间所以要深拷贝 【不知道什么是深拷贝的可以看我这篇文章类和对象【三】析构函数和拷贝构造函数】 析构函数 swap【交换函数】 因为存放数据的空间是在堆区开辟的用3个成员变量去指向的 所以直接交换两个对象的成员变量就可以了 不需要拷贝数据 赋值运算符重载 因为成员申请了堆区空间所以要深拷贝 【不知道什么是深拷贝的可以看我这篇文章类和对象【三】析构函数和拷贝构造函数】 为什么上面的两句代码就可以完成深拷贝呢 这是因为 使用了传值传参会在传参之前调用拷贝构造再把拷贝构造出的临时对象作为参数传递进去 赋值运算符的左操作数*this再与传入的临时对象obj交换就直接完成了拷贝 在函数结束之后存储在栈区的obj再函数结束之后obj生命周期结束 obj调用析构函数把指向的从*this那里交换来的不需要的空间销毁 empty size和capacity operator[] 因为 const修饰的对象只能调用const修饰的成员函数 所以const对象只会调用下面的那个重载 reserve【调整容量大小】 resize【调整size大小】 push_back assign【把所有数据替换成迭代器区间中的数据】 insert iterator insert(iterator pos, const T val){assert(pos _finish); 防止插入的位置是 越界的if (_finish _end_of_storage) 如果容量满了{记录一下扩容前的pos与start的相对位置因为扩容的话会导致pos迭代器失效size_t n pos-_start;if (capacity() 0) 如果容量为0reserve(2);else 容量不为0就扩2倍reserve(capacity() * 2);更新pospos _start n;}iterator it end()-1;把pos及其之后的数据向后挪动一位while (it pos){*(it 1) *it;it--;}_finish;*pos val;插入数据返回指向新插入的数据的迭代器 用于处理迭代器失效问题return pos-1;}为什么扩容会导致pos迭代器失效 因为扩容之后原来的空间被释放了 又因为使用的扩容方式是reserve所以那3个成员变量的值扩容后可以指向正确的位置。 但是pos如果不更新的话就还是指向被释放的空间就成了野指针了。 更新方法也很简单保存扩容之前的pos与start的相对距离n扩容之后再让pos_startn就可以了。 为什么要返回pos-1 这是stl库里面处理迭代器失效的方法之一 因为我们在使用stl库里面的insert函数的时候是不知道什么时候会扩容的【每个平台实现的vector是不同的】 只能默认使用了之后传进去pos在调用一次insert之后就失效了失效的迭代器是不能使用的。 所以如果还要用pos就要把它更新一下stl库里提供的更新方式就是 让pos接收insert的返回值。【pos是传值调用形参改变不影响实参】并且规定insert的返回值要是指向新插入的数据的迭代器 erase 为什么要返回pos 因为使用了erase之后的迭代器也会失效需要提供更新的方法 为什么使用了erase之后的迭代器会失效 不确定是否删除到一定数据时会不会减小容量以适应size 此时和insert的一样因为不能部分释放所以会把原来的空间释放掉申请新空间不确定是否删除的是最后一个数据如果是那么调用完erase之后pos指向的就 不是vector的有效数据范围了 所以和insert一样调用了erase之后如果还要使用pos就要接收返回值。 stl库里面规定erase的返回值是指向删除数据的下一个数据的迭代器因为挪动覆盖的原因下一个数据就是pos指向的数据所以返回pos【没有接收返回值的迭代器在检测较严格的编译器中不管指向的位置是否正确都会禁止使用使用了就报错】 全部代码 #includeiostream #includeassert.husing namespace std;namespace myvector {templateclass Tclass vector{public:typedef T* iterator;typedef const T* const_iterator;vector(){}vector(size_t n,const T valT()){_start new T[n];//从堆区可容纳申请n个元素大小的空间_finish _start;//还没有 有效数据 时start与finish重合_end_of_storage _start n;//指向最大容量 的 下一个位置for (size_t i 0; i n; i)//循环n次{push_back(val);//把数据尾插进去}}vector(int n, const T val T()){_start new T[n];_finish _start;_end_of_storage _start n;for (size_t i 0; i n; i){push_back(val);}}templateclass InputIteratorvector(InputIterator first, InputIterator last){//使用迭代器进行循环while (first ! last){push_back(*first);//把数据尾插进去first;}}void swap(vectorT obj){//使用库里面的swap交换3个成员变量std::swap(_start, obj._start);std::swap(_finish, obj._finish);std::swap(_end_of_storage, obj._end_of_storage);}vector(const vectorT obj){size_t size obj.size();//记录有效数据个数size_t capacity obj.capacity();//记录容量大小_start new T[capacity];//申请与obj相同大小的空间_end_of_storage _start capacity;//指向最大容量 的 下一个位置for (size_t i 0; i size; i)//循环size次{_start[i] obj._start[i];//把有效数据拷贝过去}_finish _start size;//指向最后一个有效数据的 下一个 位置}~vector(){//释放从堆区申请的空间delete[] _start;//把3个成员变量 置空_start nullptr;_finish nullptr;_end_of_storage nullptr;}vectorT operator (vectorT obj){swap(obj);return *this;}bool empty() const{//如果size等于0就是空的return size() 0;}size_t size()const{//finish指向最后一个有效数据的 下一个//start指向第一个有效数据//两个指针相减就是 两个指针之间的 数据个数return _finish - _start;}size_t capacity()const{//end_of_storage指向最大容量的 下一个位置//start指向第一个有效数据//两个指针相减就是 两个指针之间的 数据个数return _end_of_storage - _start;}T operator[] (size_t n){//防止越界访问assert(n size());//因为start是T*类型所以可以像数组一样直接随机访问return _start[n];}const T operator[] (size_t n) const{//防止越界访问assert(n size());//因为start是T*类型所以可以像数组一样直接随机访问return _start[n];}iterator begin()//普通起始迭代器{return _start;}iterator end()// 普通结束迭代器{return _finish;}const_iterator begin()const//const起始迭代器{return _start;}const_iterator end()const//const结束迭代器{return _finish;}void reserve(size_t n){if (n capacity())//要调整的容量n大于capacity才扩容{size_t origsize size();//记录扩容前的sizeT* tmp new T[n];//申请空间//把原来的数据拷贝到 新空间for (size_t i 0; i origsize; i){tmp[i] _start[i];}delete[] _start;//释放旧空间//让成员变量指向 新的空间的相对位置_start tmp;_finish _start origsize;_end_of_storage _start n;}}void resize(size_t n, const T val T()){if (size() n)//如果size与要调整的n相等return;//直接返回else if (size() n)//如果size小于n{if (n capacity())//如果n大于capacity{reserve(n);//把容量调整到n}//再把size到n 之间的空间用 val填上for (size_t i size(); i n; i){push_back(val);}}else//如果size 大于 n{//就调整标识有效数据的末尾的finish//让size_finish - _start n_finish _start n;}}void push_back(const Tval){if (_end_of_storage nullptr)//如果容量为0{reserve(2);//把容量调整到可容纳 2个元素大小}else if (_finish_end_of_storage)//容量满了{reserve(capacity()*2);//扩容}//在下标为size【最后一个有效数据的下一个】//插入值_start[size()] val;_finish;//更新有效数据的末尾}void pop_back(){assret(size() 0);_finish--;}template class InputIteratorvoid assign(InputIterator first, InputIterator last){delete[] _start;//释放原来申请的空间//把3个成员变量置空_start nullptr;_finish nullptr;_end_of_storage nullptr;while (first ! last){//一个一个尾插进去push_back(*first);first;}}iterator insert(iterator pos, const T val){assert(pos _finish);//防止插入的位置是 越界的if (_finish _end_of_storage)//如果容量满了{//记录一下扩容前的pos与start的相对位置//因为扩容的话会导致pos迭代器失效size_t n pos-_start;if (capacity() 0)//如果容量为0reserve(2);else//容量不为0就扩2倍reserve(capacity() * 2);//更新pospos _start n;}iterator it end()-1;//把pos及其之后的数据向后挪动一位while (it pos){*(it 1) *it;it--;}_finish;*pos val;//插入数据return pos-1;}template class InputIteratorvoid insert(iterator pos, InputIterator first, InputIterator last){assert(pos _finish);size_t len 0;InputIterator in first;while (in ! last){in;len;}if (_finish len _end_of_storage){size_t n pos - _start;if (capacity() 0){reserve(len);}reserve(capacity()len);pos _start n;}iterator it end() - 1;while (it pos){*(it len) *it;it--;}_finishlen;it pos;while (it ! pos len){*it *first;it;first;}}iterator erase(iterator pos){// 防止传入的pos 是越界的assert(pos _finish);iterator it pos;//把pos之后的数据都向前挪动一位把pos指向的位置给覆盖掉while (it end()-1){*it *(it 1);it;}//更新数据末尾 迭代器_finish--;//返回posreturn pos;}iterator erase(iterator first, iterator last){assert(first begin());assert(last end());iterator fi first;iterator la last;size_t len last - first;while (la ! end()){*fi *la;fi;la;}_finish - len;return first;}private://start指向从堆区申请的空间的 起始 位置与begin()返回的迭代器相等//标识有效数组的开始iterator _start nullptr;//finish指向 最后一个有效数据的 下一个位置与end()返回的迭代器相等//标识有效数据的结束iterator _finish nullptr;//_end_of_storage指向从堆区申请的空间的 末尾的 下一个位置//标识容量iterator _end_of_storage nullptr;}; }
http://www.tj-hxxt.cn/news/220662.html

相关文章:

  • 彩票网站和app建设做爰片的网站
  • asp音乐网站开发教程企业宣传ppt的方案模板
  • 平湖做网站wordpress 表情拉长
  • 凡科做的网站行不行一站式媒体发布平台
  • 体育彩票网站开发该做哪些步骤成都最正规的装修公司
  • 企业网站策划书1000字网络推广的渠道有哪些
  • linux做网站服务器做seo有什么好处
  • 微信息公众平台微网站建设做网站用空间好还是服务器好
  • 建立个人网站多少钱福步论坛外贸交流手机版
  • 用r语言 做网站点击热力图做黑网站赚钱吗
  • 济南自助建站模板wordpress博客内容预览
  • 新手学网站建设看什么书好seo优化关键词
  • 嘉峪关建设路小学网站wordpress 语言选择
  • ai的优点和缺点济南seo优化外包
  • 沣东新城开发建设集团有限公司网站直播网站开发源码下载
  • 使用html5的网站动漫制作教学
  • 贵州城乡住房和建设厅网站建设工程质量管理条例网站
  • 怎么做网站点击率监控工具实体店营销案例100例
  • 赣州网站建设服务乐山旅游 英文网站建设
  • 建立自己的网站平台的好处建设企业管理类网站
  • 嘉兴行业网站建设泰州网页网站制作
  • 做阿里巴巴跟网站哪个更好360网站建设公司哪家好
  • 济南网站优化推广公司北京网站seo公司
  • 重庆建设网站首页凡科建站快车代理登录
  • 校园网站建设的感受论文网站优化 秦皇岛
  • 从零开始学习网络营销长春企业网站seo
  • 网站备案域名用二级域名青岛seo全网营销
  • 安徽网站建设wordpress文章标记
  • 防城港北京网站建设做ppt的模板的网站
  • 创立网站做电商企业微信营销系统