1. 反向迭代器:从源码到实现的深度解析
反向迭代器是STL中一个强大但常被忽视的组件,它允许我们以逆序方式遍历容器。理解它的实现原理不仅能提升我们对STL设计的认识,更能帮助我们在需要自定义迭代器时游刃有余。
1.1 反向迭代器的核心思想
反向迭代器的本质是一个适配器(Adapter)模式的应用。它不直接访问容器元素,而是通过封装正向迭代器来实现逆向遍历。这种设计有三大优势:
- 代码复用:避免为每个容器重复实现逆向遍历逻辑
- 一致性:所有容器的反向迭代器具有相同接口
- 灵活性:可以适配任何满足要求的正向迭代器
关键设计决策:
- 解引用时访问前一个元素(
*--tmp) rbegin()对应end()位置rend()对应begin()位置
这种对称设计确保了:
- 完整覆盖所有元素
- 与正向迭代器行为一致
- 边界条件处理自然
1.2 STL源码实现剖析
在SGI-STL实现中,反向迭代器有两个版本:
cpp复制// 新版(支持偏特化)
template <class Iterator>
class reverse_iterator {
Iterator current;
//...操作符重载
};
// 旧版(显式指定类型)
template <class BidirectionalIterator, class T, class Reference, class Distance>
class reverse_bidirectional_iterator {
BidirectionalIterator current;
//...操作符重载
};
关键操作实现原理:
cpp复制reference operator*() const {
Iterator tmp = current;
return *--tmp; // 关键点:访问前一个元素
}
self& operator++() {
--current; // 反向++实为正向--
return *this;
}
这种实现方式确保了:
rbegin()到rend()的范围正好覆盖全部元素- 与正向迭代器的对称性
- 高效的遍历操作(O(1)时间复杂度)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 手把手实现反向迭代器
2.1 基础框架搭建
我们首先定义反向迭代器的模板类:
cpp复制template<class Iterator, class Ref, class Ptr>
struct ReverseIterator {
typedef ReverseIterator<Iterator, Ref, Ptr> Self;
Iterator _it; // 封装的正向迭代器
// 构造函数
ReverseIterator(Iterator it) : _it(it) {}
// 解引用操作
Ref operator*() {
Iterator tmp = _it;
return *(--tmp);
}
// 指针操作
Ptr operator->() {
return &(operator*());
}
};
2.2 迭代器移动操作实现
实现前向和后向移动:
cpp复制// 前置++
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;
}
2.3 容器集成示例
在vector中的集成方式:
cpp复制template<class T>
class vector {
public:
typedef T* iterator;
typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
reverse_iterator rbegin() {
return reverse_iterator(end());
}
reverse_iterator rend() {
return reverse_iterator(begin());
}
};
在list中的集成方式:
cpp复制template<class T>
class list {
typedef ListNode<T> Node;
public:
typedef ListIterator<T, T&, T*> iterator;
typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
reverse_iterator rbegin() {
return reverse_iterator(end());
}
reverse_iterator rend() {
return reverse_iterator(begin());
}
};
2.4 实战测试代码
cpp复制void TestReverseIterator() {
// 测试vector反向迭代器
vector<int> v = {1, 2, 3, 4};
cout << "Vector reverse: ";
for(auto rit = v.rbegin(); rit != v.rend(); ++rit) {
cout << *rit << " "; // 输出:4 3 2 1
}
// 测试list反向迭代器
list<int> lt = {1, 2, 3, 4};
cout << "\nList reverse: ";
for(auto rit = lt.rbegin(); rit != lt.rend(); ++rit) {
cout << *rit << " "; // 输出:4 3 2 1
}
}
3. 逆波兰表达式:从理论到实践
3.1 表达式表示法对比
| 表示法 | 示例 | 特点 |
|---|---|---|
| 中缀 | 1 + 2 * 3 |
需要优先级处理,人类易读 |
| 前缀 | + 1 * 2 3 |
运算符在前,无需括号 |
| 后缀 |
