漳州手机网站建设,长春建设信息网站,ios 软件开发,微商的自己做网站叫什么软件目录
1. 读源码
2. 搭建框架
3. 迭代器的操作
operator*()
operator-()
operator()
operator--()
operator!()
4. 实现 list 的反向迭代器
5. 实现 vector 的反向迭代器
6. 源码分享
写在最后#xff1a; 1. 读源码
我们之前实现的 vector#xff0c;list…目录
1. 读源码
2. 搭建框架
3. 迭代器的操作
operator*()
operator-()
operator()
operator--()
operator!()
4. 实现 list 的反向迭代器
5. 实现 vector 的反向迭代器
6. 源码分享
写在最后 1. 读源码
我们之前实现的 vectorlist 好像都只实现了他们的正向迭代器那有正向
会有反向迭代器这种东西吗答案是有的那我们该怎么实现呢
实际上根据我们之前的经验根据每个容器的特色实现一份就好了
但是之前在读源码的时候好像并没有看到源码实现这是怎么一回事呢
来读读 list 的源码是怎么做的 我们在这里找到了 list 的反向迭代器他没有自己实现
而是直接使用了这个 reverse_iterator 的类模板这又是怎么一回事呢
我们在 STL 源码的 stl_iterator.h 文件中找到了答案 这里面竟然存在这样一个类reverse_iterator难道说其他的容器
也都不是自己实现一份反向迭代器而是直接使用这个类吗
想到这里我们赶紧去看一眼 vector 的源码 发现了没有他们的调用方式是一模一样的都是同样的调用
使用的类型是他们各自的迭代器类型通过模板的特性
让编译器实例化出不同的代码达成实现他们各自的迭代器的目的
非常巧妙的设计只一份代码让所有的容器的反向迭代器都复用
那他是怎么实现的呢我们来看看他实现的源码 我们可以看到这个就是迭代器类型的成员变量了。
还是老规矩看完成员变量我们去看一下核心的接口实现
先来看 的重载 他的 就是让原先的正向迭代器执行 -- 操作没毛病
再来看 -- 的重载 也没毛病我们再来看看他的解引用操作 这下怪了为啥解引用取到的位置是原先位置的前一个位置呢
那我们就得去看看那些容器的反向迭代器是怎么确定初始位置的了
先来看 list 的 正向迭代器的 begin 就是第一个位置end 就是哨兵位的头结点
但是 rbegin 用的是 end 来初始化反向迭代器也就是他在 end 的位置哨兵位上
而 rend 用的是 begin 来初始化反向迭代器也就是他在 begin 的位置第一个位置上
我们也可以看一下 vector 是不是这样的 可以看到也是这样的。
那这样好像不太对啊如果直接使用迭代器
第一次解引用就会出问题这里我写段伪代码感受一下
rit rbegin()
while(rit ! rend()) { cout *rit endl; // 这里就出问题了 rit;
}
所以库里在实现的解引用操作符的时候解引用的就是他的前一个位置
我再截出来看一眼 现在看的也差不多了马上开始动手实现吧~
2. 搭建框架
namespace xl {template class Iteratorclass reverse_iterator {private:Iterator _it;public:reverse_iterator(Iterator it): _it(it){}};
}其实框架就一点点啦
就是写个成员变量写个构造函数就差不多完成啦。
3. 迭代器的操作
operator*()
我们直接上手
operator*() {Iterator tmp _it;return *(--tmp);
}
这个时候我们遇到了一些困难
我们该怎么返回这个值呢还是跟之前一样我们需要让他支持 const 类型
先来看看源码是怎么实现的 他这里的 reference 通过了一系列的复杂操作然后套了出来
这里他用的操作是萃取比较的麻烦还涉及模板的特化
所以我们打算用一个比较方便暴力的方法就是通过模板参数直接传过来 Ref operator*() {Iterator tmp _it;return *(--tmp);
}
这样下面的实现也解决了
operator-()
Ptr operator-() {return (operator*());
}
operator()
这里我们再顺便把类名 typedef 一下因为他太长了 然后来实现 这里我都是前置和后置都实现了
self operator() {--_it;return *this;
}self operator(int) {self tmp _it;--_it;return tmp;
}
operator--()
self operator--() {_it;return *this;
}self operator--(int) {self tmp _it;_it;return tmp;
}operator!()
直接用正向迭代器的 ! 比较即可
bool operator!(const self s) {return _it ! s._it;
}
4. 实现 list 的反向迭代器
typedef reverse_iteratoriterator, const T, const T* const_reverse_iterator;
typedef reverse_iteratoriterator, T, T* reverse_iterator;reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return reverse_iterator(begin()); } 我们来测试一下
#include iterator.h
#include list.hint main()
{xl::listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt) cout e ;cout endl;xl::listint::reverse_iterator rit lt.rbegin();while (rit ! lt.rend()) {cout *rit ;rit;}cout endl;return 0;
}
输出 输出没毛病~
5. 实现 vector 的反向迭代器
跟 list 一模一样的操作直接把代码粘过来即可
然后我们直接测试
void test_vector() {xl::vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto e : v) cout e ;cout endl;xl::vectorint::reverse_iterator rit v.rbegin();while (rit ! v.rend()) {cout *rit ;rit;}cout endl;
}
输出 结果也没毛病~
6. 源码分享
模拟实现简易STL: 模拟实现简易STL (gitee.com)
写在最后
以上就是本篇文章的内容了感谢你的阅读。
如果感到有所收获的话可以给博主点一个赞哦。
如果文章内容有遗漏或者错误的地方欢迎私信博主或者在评论区指出~