网站流量查询网站统计查询,校园网站建设成本,pc蛋蛋网站开发,摄影师网站模板前文本篇文章准备换个模式#xff0c;之前都是先详解模拟实现#xff0c;但是模拟实现的基本逻辑大多数老铁都是明白的#xff0c;所以我们这次主要讲解STL库中list的独特性#xff0c;也就是模拟实现中的重难点文末有模拟实现的源码一#xff0c;list实现的特殊类list实现…前文本篇文章准备换个模式之前都是先详解模拟实现但是模拟实现的基本逻辑大多数老铁都是明白的所以我们这次主要讲解STL库中list的独特性也就是模拟实现中的重难点文末有模拟实现的源码一list实现的特殊类list实现和前面vectorstring最大的区别莫过于单独封装了迭代器。我们通常使用的迭代器分为两种1.原生指针作为迭代器。如vectorstring。2.自定义类型对原生指针进行封装模拟指针的行为。如list。vectorlist:在list中我们对原生指针进行封装模拟指针的行为因此我们需要在该类中实现*(),-,前置,后置前置--后置--!,等函数重载这时候可能有的老铁对迭代器模板中三个模板参数感到惊讶下面我们就来讲解一下。二迭代器模板中的多个模板参数如图迭代器模板参数中定义了三个模板参数这是为什么呢要注意这里是list中模板非常非常巧妙的一种用法。第一个T就不用多说了和vector中的模板参数意义一样。我们重点说第二和第三个.2.1 Ref模板参数Ref模板参数的产生主要是因为*()操作符重载在实际的应用中我们的list可能会被const修饰导致里面的值只能读取不能修改而如果用第一个模板参数我们则无法实现 const修饰返回值因此我们专门写了第二个模板参数Ref来应对这种情况。如上图所示右边const修饰的list其中的值无法改变我们会直接调用const_iterator迭代器进行模板实例化这样Ref的值就为const T,至此我们就借助了第二个模板参数实现了正常迭代器和const修饰的迭代器的区分.2.2 Ptr模板参数Ptr模板参数是专门给-操作符重载准备的.没有Ptr的话应该是这样我们多一个模板参数的原因和Ref的原因一样都是为了应对list被const修饰无法改变的情况但是list迭代器中-操作符重载有一个重要的特性。如下所示图中第313行和314行代码不一样但执行效果却一样为什么呢根据语法313行想访问_a1应该这样写it--_a1但it-_a1却也可以为什么呢这是因为在这里我们为了增强可读性省略了一个-。三源码#pragma once
#include iostream
#include assert.h
using namespace std;
namespace mjw
{templateclass Tstruct list_node{list_nodeT* _prev;list_nodeT* _next;T _data;list_node(const T valT()):_prev(nullptr),_next(nullptr),_data(val){}};templateclass T,class Ref,class Ptrstruct _list_iterator{typedef list_nodeT node;typedef _list_iteratorT, Ref,Ptr iterator;node* _node;_list_iterator(node* n):_node(n){}//*()重载Ref operator*(){return _node-_data;}//-重载T* operator-(){return _node-_data;}//前置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;}//!重载bool operator!(const iterator ls){return _node ! ls._node;}//重载bool operator(const iterator ls){return _node ls._node;}};templateclass Tclass list{public:typedef list_nodeT node;typedef _list_iteratorT,T,T* iterator;typedef _list_iteratorT,const T,const T* const_iterator;void empty_init(){_head new node;_head-_next _head;_head-_prev _head;}//构造list(){empty_init();}//区间构造//先初始化然后一个一个尾插templateclass InputIteratorlist(InputIterator first, InputIterator last){empty_init();while (first ! last){push_back(*first);first;}}void swap(listT tmp){std::swap(_head, tmp._head);}//拷贝构造list(const listT lt){empty_init();listT tmp(lt.begin(),lt.end());swap(tmp);}//赋值listT operator(listT lt){swap(lt);return *this;}//析构~list(){delete _head;_head _head-_next _head-_prev nullptr;}//clearvoid clear(){iterator cur begin();while (cur ! end()){erase(cur);}}//begin()iterator begin(){return iterator(_head-_next);}const_iterator begin() const{return const_iterator(_head-_next);}//end()iterator end(){return iterator(_head);}const_iterator end() const{return const_iterator(_head);}//尾插void push_back(const T val){/*node* newnode new node(val);node* next _head;node* prev _head-_prev;newnode-_next next;newnode-_prev prev;prev-_next newnode;next-_prev newnode;*/insert(end(), val);}//尾删void pop_back(){erase(--end());}//头插void push_front(const T val){insert(begin(), val);}//头删void pop_front(){erase(begin());}void insert(iterator pos, const T val){node* newnode new node(val);node* next pos._node;node* prev next-_prev;newnode-_next next;newnode-_prev prev;prev-_next newnode;next-_prev newnode;}//为了防止迭代器失效返回要删除的迭代器的下一个数据iterator erase(iterator pos){assert(pos._node ! _head);node* prev pos._node-_prev;node* next pos._node-_next;prev-_next next;next-_prev prev;delete pos._node;pos._node nullptr;return iterator(next);}private:node* _head;};}