佛山品牌网站设计制作,wordpress获取用户昵称,石家庄裕华区网站建设,想做微商怎么找厂家反向迭代器的即正向迭代器的--#xff0c;反向迭代器的--即正向迭代器的#xff0c;反向迭代器和正向迭代器的很多功能都是相似的#xff0c;因此我们可以复用正向迭代器作为反向迭代器的底层容器来封装#xff0c;从而实现出反向迭代器#xff0c;即#xff1a;反向迭代…反向迭代器的即正向迭代器的--反向迭代器的--即正向迭代器的反向迭代器和正向迭代器的很多功能都是相似的因此我们可以复用正向迭代器作为反向迭代器的底层容器来封装从而实现出反向迭代器即反向迭代器内部可以包含一个正向迭代器对正向迭代器的接口进行包装
这样一来我们可以实现任意容器的反向迭代器如果用的是vector的正向迭代器那么就封装出vector的反向迭代器如果用的是list的正向迭代器那么就封装出list的反向迭代器这就是迭代器适配器了
反向迭代器
templateclass Iterator,class Ref,class Ptr
class ReverseIterator
{typedef ReverseIteratorIterator, Ref, Ptr Self;
public:ReverseIterator(Iterator it):_it(it){}Self operator(){--_it;return *this;}Self operator(int){Self tmp(*this);--_it;return tmp;}Self operator--(){_it;return *this;}Self operator--(int){Self tmp(*this);_it;return tmp;}Ref operator*()//返回前一个位置的数据{Iterator cur _it;return *(--cur);}Ptr operator-(){return (operator*());}bool operator!(const Self s){return _it ! s._it;}bool operator(const Self s){return _it s._it;}private:Iterator _it;
};库中设计的反向迭代器与正向迭代器是对称关系关于解引用越界问题也很巧妙的处理了~
解引用返回的是前一个位置的数据 vector模拟实现
#includeassert.h
#includeReverseiterator.h
namespace djx
{templateclass Tclass vector{public:typedef T* iterator;typedef const T* const_iterator;typedef ReverseIteratoriterator, T, T* reverse_iterator;typedef ReverseIteratorconst_iterator, const T, const T* const_reverse_iterator;reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rbegin() const{return const_reverse_iterator(end());}const_reverse_iterator rend() const{return const_reverse_iterator(begin());}iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin()const{return _start;}const_iterator end()const{return _finish;}vector()//一定要写因为我们已经写了拷贝构造了编译器不会生成默认的构造函数当要使用无参的构造时如果我们没写就没有会报错{}vector(const vectorT v){reserve(v.capacity());for (auto e : v){push_back(e);}}vector(size_t n, const T val T()){reserve(n);for (size_t i 0; i n; i){push_back(val);}}template class InputIteratorvector(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;}~vector(){delete[] _start;_start _finish _endofstorage nullptr;}T operator[](size_t pos){assert(pos size());return _start[pos];}const T operator[](size_t pos) const{assert(pos size());return _start[pos];}void reserve(size_t n){if (n capacity()){size_t sz size();T* tmp new T[n];if (_start){for (size_t i 0; i sz; i){tmp[i] _start[i];}delete[] _start;}_start tmp;_finish _start sz;_endofstorage _start n;}}void push_back(const T val){/* if (_finish _endofstorage){reserve(capacity() 0 ? 4 : capacity() * 2);}*_finish val;_finish;*/insert(end(), val);//复用insert}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 insert(iterator pos, const T val){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 val;_finish;}iterator erase(iterator pos){assert(pos _start);assert(pos _finish);iterator begin pos 1;while (begin _finish){*(begin - 1) *begin;begin;}_finish--;return 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;};
}测试vector的反向迭代器
void func(const djx::vectorint v)
{djx::vectorint::const_reverse_iterator rit v.rbegin();while (rit ! v.rend()){cout *rit ;rit;}cout endl;
}int main()
{djx::vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);djx::vectorint::reverse_iterator rit v.rbegin();while (rit ! v.rend()){cout *rit ;rit;}cout endl;func(v);return 0;
} list模拟实现
#includeReverseiterator.h
namespace djx
{templateclass Tstruct list_node{T _data;list_nodeT* _prev;list_nodeT* _next;list_node(const T x T()):_data(x), _prev(nullptr), _next(nullptr){}};templateclass T, class Ref, class Ptrstruct __list_iterator{typedef list_nodeT Node;typedef __list_iteratorT, Ref, Ptr self;Node* _node;__list_iterator(Node* node):_node(node){}Ref operator*(){return _node-_data;}Ptr operator-(){return _node-_data;}self operator(){_node _node-_next;return *this;}self operator(int){self tmp(*this);_node _node-_next;return tmp;}self operator--(){_node _node-_prev;return *this;}self operator--(int){self tmp(*this);_node _node-_prev;return tmp;}bool operator!(const self s){return _node ! s._node;}bool operator(const self s){return _node s._node;}};templateclass Tclass list{typedef list_nodeT Node;public:typedef __list_iteratorT, T, T* iterator;typedef __list_iteratorT, const T, const T* const_iterator;typedef ReverseIteratoriterator, T, T* reverse_iterator;typedef ReverseIteratorconst_iterator, const T, const T* const_reverse_iterator;reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rbegin()const{return const_reverse_iterator(end());}const_reverse_iterator rend() const{return const_reverse_iterator(begin());}iterator begin(){return _head-_next;}iterator end(){return _head;}const_iterator begin()const{return _head-_next;}const_iterator end()const{return _head;}void empty_init(){_head new Node;_head-_next _head;_head-_prev _head;_size 0;}list(){empty_init();}list(const listT lt){empty_init();for (auto e : lt){push_back(e);}}void swap(listT lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}listT operator(listT lt){swap(lt);return *this;}~list(){clear();delete _head;_head nullptr;}void clear(){iterator it begin();while (it ! end()){it erase(it);}}void push_back(const T x){insert(end(), x);}void push_front(const T x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}iterator insert(iterator pos, const T x){Node* cur pos._node;Node* newnode new Node(x);Node* prev cur-_prev;prev-_next newnode;newnode-_prev prev;newnode-_next cur;cur-_prev newnode;_size;return newnode;}iterator erase(iterator pos){Node* cur pos._node;Node* next cur-_next;Node* prev cur-_prev;delete cur;prev-_next next;next-_prev prev;_size--;return next;}size_t size(){return _size;}private:Node* _head;size_t _size;};
}测试list的反向迭代器
void func(const djx::listint lt)
{djx::listint::const_reverse_iterator rit lt.rbegin();while (rit ! lt.rend()){cout *rit ;rit;}cout endl;
}int main()
{djx::listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);djx::listint::reverse_iterator rit lt.rbegin();while (rit ! lt.rend()){cout *rit ;rit;}cout endl;func(lt);return 0;
} 当然了我们也可以按照不同于库中设计的逻辑来设计反向迭代器但是存在一些细节需要处理
与库中反向迭代器设计模式不同之处在于解引用的设计 上图版本的反向迭代器解引用重载的设计 Ref operator*(){return *_it} 那么相应的在vector和list中也会发生变化
vector中 reverse_iterator rbegin(){return reverse_iterator(end() - 1);}reverse_iterator rend(){return reverse_iterator(begin() - 1);}const_reverse_iterator rbegin() const{return const_reverse_iterator(end() - 1);}const_reverse_iterator rend() const{return const_reverse_iterator(begin() - 1);}
需要注意的是必须是end()-1 /begin()-1 而不能是--end()/--begin()
因为vector类中迭代器的实现我们将其设计为原生指针T*是内置类型 end()/begin() 为传值返回返回的是临时对象具有常性不可被修改
list中 reverse_iterator rbegin(){return reverse_iterator(--end());}reverse_iterator rend(){return reverse_iterator(end());}const_reverse_iterator rbegin() const{return const_reverse_iterator(--end());}const_reverse_iterator rend() const{return const_reverse_iterator(end());}也可以设计成end()-1,只不过list的正向迭代器是自定义类型需要重载-运算符才可 那么问题就来了为什么同样是各自的--end() vector就报错我们知道因为返回的是临时对象具有常性导致的但是list却不报错可以这样设计呢
诚然list的end返回的也是临时对象同样具有常性不报错是因为这是特殊情况特殊处理具有常性的自定义类型的对象可以调用非const的函数
所以list中的--end返回的自定义类型的临时对象可以调用list迭代器类中非const的--运算符重载函数
如
class A
{
public:A(int x 0):_a(x){}void Print(){}private:int _a;
};我们有时候会写出这样的代码
A(1).Print(); // 特殊处理
A1是匿名对象具有常性而print函数是非const的