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

东莞专业网站设计建站公司免费网站入口网站免费进

东莞专业网站设计建站公司,免费网站入口网站免费进,网络门店管理系统登录入口,ui设计培训机构怎么样#x1f493;博主CSDN主页:杭电码农-NEO#x1f493;   ⏩专栏分类:C从入门到精通⏪   #x1f69a;代码仓库:NEO的学习日记#x1f69a;   #x1f339;关注我#x1faf5;带你学习C   #x1f51d;#x1f51d; list模拟实现 1. 前言2. list类的大致框架与结构… 博主CSDN主页:杭电码农-NEO   ⏩专栏分类:C从入门到精通⏪   代码仓库:NEO的学习日记   关注我带你学习C   list模拟实现 1. 前言2. list类的大致框架与结构3. List类的构造,析构,拷贝构造4. list的迭代器的实现4.1 list迭代器的若干函数解析4.2 list迭代器的解引用和箭头操作4.3 迭代器类映射到list类 5. const迭代器实现深度剖析5.1 const迭代器实现详解5.2 const迭代器和list类的复用5.3 const迭代器使用实例 6. list和vector的对比7. 总结以及代码分享 1. 前言 本篇文章立足于上一篇文章: list深度剖析(上) 请先阅读完上一篇文章后再阅读这篇文章! 本章重点: 本章着重讲解list的模拟实现 list模拟实现的重难点是迭代器的实现 和const迭代器的实现 最后总结list和vector的区间对比 注:我将在文章末尾分享list模式实现全部代码 2. list类的大致框架与结构 由于list类是一个带头双向循环链表 所以在写list类之前,应该先定义节点类 在真正的list类中会复用此类: templateclass T class list_node { public:T _data;list_nodeT* _next;list_nodeT* _prev;list_node(const T x T()):_data(x), _next(nullptr), _prev(nullptr){} };这个类和用C语言实现链表的定义很像 节点中存储一个T模板类型的值和 上一个节点的地址和下一个节点的地址 在List类中,由于链表都是些链接关系 所以List类中的成员变量只需要定义一个 那就是头节点head,知道head的链接关系 就知道list类对象中存放的内容! List类基本框架以及无参构造: templateclass T class List {typedef list_nodeT node; public:List(){_head new node;_head-_next_head;_head-_prev_head;} private:node* _head; }给头节点head开辟一份空间后 头节点的指向最开始都是指向自身: 3. List类的构造,析构,拷贝构造 无参构造函数以及写过了,我们模仿 STL库中的带参构造写一个用迭代器 区间初始化的构造函数: void emptyinit()//创建并初始化哨兵位的头节点,方便给构造和拷贝构造复用{_head new node;_head-_next _head;_head-_prev _head;} templateclass InputTterator//有参的构造 List(InputTterator first, InputTterator last) {emptyinit();while (first ! last){push_back(*first);first;} }注:push_back先用着,后面会实现 在实现析构函数前,我们可以先实现clear函数 因为析构函数实际上可以复用clear函数: void clear()//清空数据,除了头节点 {iterator it begin();while (it ! end()){it erase(it);//erase会返回下一个节点的迭代器} }~List()//_head也要被删除掉 {clear();delete _head;_head nullptr; }注:迭代器相关的函数先用着,后面会实现 拷贝构造函数的实现:(用lt1拷贝lt2) //lt2(lt1) List(const ListT lt)//完成深拷贝 {emptyinit();ListT tmp(lt.begin(), lt.end());//用lt1的迭代器区间去构造一下tmp::swap(_head, tmp._head); }此拷贝构造函数精妙的地方有两个: 它先定义一个临时变量tmp来接受 lt1的所有值,然后再将临时变量tmp 的head和lt2的head交换,这样一来 lt2中的链接关系就和lt1相同了 并且tmp变量是构造函数初始化的 它是深拷贝,所以lt2对于lt1也是深拷贝 tmp是临时变量,除了作用域会销毁 也就是除了此拷贝构造函数后会销毁 销毁时会调用析构函数,然而lt2的head 以及和tmp的head交换了,所以tmp销毁 时实际上是在帮原先的lt2销毁内存! 4. list的迭代器的实现 由于list的迭代器底层不是简单的指针 所以我们不能像实现vector一样直接在 list类定义迭代器和使用迭代器相关函数 要重新写一个迭代器类来实现功能: templateclass T struct __list_iterator {typedef list_nodeT node;typedef __list_iterator iterator;node* _node; }这样重新写一个类的作用是将迭代器的 ,- -等操作在此类中实现,因为list中的 实际上是nodenode-next,然而list 中的符号判断的是node1-data和 node2-data相不相同,如果迭代器和 list写在一个类中,实现此等操作会很麻烦 4.1 list迭代器的若干函数解析 1. 构造函数: __list_iterator(node* nnode):_node(nnode){}由于初始化列表会调用node的构造函数 所以list迭代器的构造函数可写可不写 2. 前置/- -和后置/- - iterator operator()//前置 {_node _node-_next;return *this; } iterator operator(int)//后置 {iterator tmp *this;_node _node-_next;return tmp; } iterator operator--()//前置-- {_node _node-_prev;return *this; } iterator operator--(int)//后置-- {iterator tmp *this;_node _node-_prev;return tmp; }3. 等于和不等于函数解析: bool operator!(const iterator it)const {return _node ! it._node; } bool operator(const iterator it)const {return _node it._node; }4.2 list迭代器的解引用和箭头操作 迭代器的使用就像指针一样,所以 解引用后应该直接得到节点的数据! 由于结构体变量除了可以用解引用 以外还能使用-,所以需要写两个函数: //可读可写 T operator*() {return _node-_data; } //可读可写 T* operator-() {return (operator*()); }解引用操作的应该没有问题 重点难点在这个箭头-函数 可以将这个函数一步一步拆分: return (_node-_data);相当于返回了一个结构体指针 然而我们想要的并不是一个结构体指针 而是确切的值,蛋这样写编译器并不会报错 这是因为编译器为了代码的可读性 帮我们省略了一个箭头- 所以只需要一个箭头-就能访问数据! 注:省略的箭头可以将返回的结构体指针解引用 然而此结构体指针解引用后其实就是data 4.3 迭代器类映射到list类 当我们实现完迭代器类后 就可以在list类中复用迭代器类了: templateclass T class List {typedef list_nodeT node;typedef __list_iteratorT iterator; private:node* _head;有了迭代器类的加持后,list类中的 其他函数如begin和end就是歪瓜裂枣了 iterator begin() {//iterator tmp(_head-_next);//return tmp;return iterator(_head-_next);//使用了匿名对象 } iterator end() {//iterator tmp(_head);//return tmp;return iterator(_head); }注:其他关于迭代器的函数会在最后放出 5. const迭代器实现深度剖析 既然list中的迭代器和vector中的不同 那么const迭代器的实现当然也不同 首先我们要明白一点,list的普通迭代器 和const迭代器的区别到底是什么? const对象的剖析: const迭代器是为const对象准备的 然而const对象的特征就是不能修改 那么什么操作会让对象的值变化呢? 答案很明显是解引用操作和箭头- begin和end函数返回后也有可能被修改 注:返回值是T和T*的函数都要注意 解决方案剖析: 大家可能第一时间想到再重新写一个 const迭代器的类,里面的实现和普通 迭代器都一样,唯一不同的是解引用函数 和箭头-函数的返回值是const对象 5.1 const迭代器实现详解 首先,不用再重新写一个类来实现 接下来的方案不要问为什么 不要问怎么想到的,是天才想到的: 在普通迭代器类中使用三个模板参数 为什么要这样做? 通过观察可以发现,只有两个函数不同 并且这两个函数的类型只有T和T* 那么就专门为这两个类型设置两个模板 只有在编写这两个函数时用到这两个模板 其余函数还是正常的使用T来当类型 话不多说,上代码 templateclass T, class Ref, class Ptr struct __list_iterator//迭代器不需要析函数 {typedef list_nodeT node;typedef __list_iterator iterator;node* _node; }模板中的Ref代表的是引用 模板中的Ptr代表的是指针 * 现在重新来实现一下这两个函数: //按模板参数来 Ref operator*() {return _node-_data; } Ptr operator-() {return (operator*()); }现在你脑子肯定是一篇空白 但是精髓的地方马上就来了,请耐住性子 5.2 const迭代器和list类的复用 当list类复用了此迭代器类后: templateclass T class List {typedef list_nodeT node;typedef __list_iteratorT, T, T* iterator;typedef __list_iteratorT, const T, const T* const_iterator; private:node* _head; }这样写出来后,普通迭代器和const迭代器 就被完美的区别开了,当传入const对象时 系统会把模板参数实例化为const T 当传入的是普通对象时,系统会把模板参数 实例化为普通的T,T和T* begin和end函数的复写: const_iterator begin()const {return const_iterator(_head-_next); } iterator begin() {return iterator(_head-_next);//使用了匿名对象 } const_iterator end()const {return const_iterator(_head); } iterator end() {return iterator(_head); }5.3 const迭代器使用实例 现在,我们通过一个实例来感受这一过程: void print_list(const listint lt) {auto it lt.begin();while (it ! lt.end()){//*it 10;cout *it ;it;}cout endl; }此时的lt变量是const变量,实例化类时 会实例化为T,const T,const T* 然后回退到迭代器类时,迭代器类的 模板参数Ref就对应:const T 模板参数Ptr就对应:const T* 此时解引用函数的返回值就是const T 如果你写:*it10;那么就会报错! 6. list和vector的对比 详情请看下表: 目录vectorlist底层结构顺序表,空间连续带头双向循环链表随机访问支持随机访问,访问效率为O(1)不支持随机访问,访问效率为O(N)插入和删除任一位置插入删除效率低,还需扩容任一位置插入效率高空间利用率空间,缓存利用率高不连续空间,容易造成内存碎片迭代器原生态的指针对原生指针的封装迭代器失效插入和删除都会导致只有删除会导致使用场景高效存储支持随机访问有大量插入和删除操作不关心随机访问 注:这个表格不能死记硬背,要理解记忆 7. 总结以及代码分享 总的来说,list的底层实现较于vector 来说要复杂一点,这其中的底层原因 就是list的迭代器还需要一层封装,而 vector的迭代器不需要额外封装 C的强大就在于把复杂的底层 全部封装起来了,而表面的使用上 list和vector并无太大区别,这就是 C封装的魅力! list模拟实现全部代码分享: List模拟实现全部代码 注:全部代码中包含反向迭代器 目前阶段可以跳过不管 下期预告:栈和队列
http://www.hkea.cn/news/14257657/

相关文章:

  • 公司网站设计与实现的项目建议书电商网站开发的代价
  • asp.net电子商务网站前台模板昌大建设土地建设
  • 用html编写淘宝网站怎么做怎样网站建设与管理
  • 企业网站建设找哪家做微信的网站叫什么名字
  • 长沙网站建设qq交流群做论坛app网站有哪些
  • 微网站矩阵怎么做网站地图怎么做XML
  • 培训方案网站建设wordpress页面无法编辑
  • 正规绍兴网站建设公司五屏网站建设公司
  • 网站做外链推广的常用方法外包小程序开发技巧
  • 怎么向百度提交网站发帖推广
  • 深圳服装网站建设制作开发淮北招聘网
  • wordpress站长统计青少年宫网站开发
  • 建设网站视频手机端 网站 模板
  • 网站上传不了wordpress 重定向插件
  • 运营平台济南优化排名公司
  • 网站页面怎么做地图ui设计网站开发
  • 无锡网站建设机构江苏城乡与住房建设厅网站
  • 网站制作软件培训国外WordPress主题速度慢
  • 网站开发成本核算及账务处理最新流行网站开发技术
  • 有哪些可以接单做任务的网站无锡网站建设制作
  • 公司网站开发找哪家初中毕业学网站开发工程师
  • dede 购物网站网站建设时送的ppt方案
  • 网站自动更新时间代码网站图片怎么做优化
  • 微信服务号绑定网站网站开发技术人员
  • 网站建设二级页面方案做个淘宝客网站怎么做的
  • 做黄金的经常看什么网站wordpress博客福利网整站源码
  • 如何造网站wordpress动漫电影主题
  • 企业网站策划方案书做电商设计在哪个网站接单
  • 昆明比较好的网站开发公司交互设计精髓
  • 丽水网站建设企业app软件开发公司怎么选